28
sha1sum ./path/to/directory/* | sha1sum 

вышеприведенное было опубликовано как способ вычисления совокупности каталогов, содержащих файлы. Эта команда не выполняется, если каталог содержит больше каталогов. Есть ли способ рекурсивного вычисления Sha1sum каталога каталогов универсально (без пользовательской подгонки алгоритма к конкретному рассматриваемому каталогу)?

10 ответов10

38

Мне обычно нравится шаблон "find | xargs", например:

find ./path/to/directory/ -type f -print0  | xargs -0 sha1sum

Вы должны использовать «-print0» и «-0», если в именах файлов есть пробелы.

Однако это очень похоже на шаблон «find -exec cmd {}».

Смотрите обсуждение, сравнивая два шаблона здесь: https://stackoverflow.com/questions/896808/find-exec-cmd-vs-xargs

13

Благодаря этому так посту -

find . -type f \( -exec sha1sum "$PWD"/{} \; \) | sha1sum

Предупреждение: этот код не проверен ! Отредактируйте этот вопрос, если он неправильный, и вы можете это исправить; Я одобрю ваше редактирование.

4

ВСТУПЛЕНИЕ

Несколько лет назад я написал и представил (в этой самой теме) скрипт, который может проверять хэш-подписи всех отдельных файлов в текущей структуре каталогов и выводить их в виде списка в текстовом файле.

С тех пор я несколько раз улучшал эту формулу. Я решил опубликовать свой новый и улучшенный сценарий в качестве отдельного ответа. Он написан для sha256, но любой, кто все еще хочет использовать sha1, может выполнить простой поиск и заменить его в gedit, чтобы заменить sha256 на sha1. Лично я пару лет не использовал sha1 и не рекомендовал бы его, так как он устарел, и Google продемонстрировал, как его можно скомпрометировать.

Вот что делает мой новый скрипт:

  1. Вы можете просто использовать скрипт, перейдя в каталог, который вы хотите хэшировать и введя:

    sha256rec
    

    Кроме того, вы можете вызвать этот скрипт из другого каталога, выполнив:

    sha256rec "/path/to/target/directory/you/want/hash"
    
  2. Скрипт определит, есть ли у вас права на запись в текущем каталоге. Если вы это сделаете, результаты будут сохранены в текущем каталоге. Если у вас нет прав на запись или ваш текущий каталог находится в системе только для чтения (например, cdrom), результаты будут сохранены в домашнем каталоге текущего пользователя.

  3. Скрипт обнаружит, если некоторые из подкаталогов недоступны с текущими привилегиями пользователя. Если все доступно для чтения, повышения привилегий не происходит, если нет, то привилегии пользователя повышаются до уровня root.

  4. Find используется для поиска всех файлов в текущей структуре dir (включая все подкаталоги). Сортировка используется, чтобы убедиться, что результаты выводятся в алфавитном порядке. Результирующий список подвергается sha256sum и выводится в текстовый файл.

  5. Со времени написания старого скрипта я принял философию дизайна, согласно которой временные файлы являются злыми, и их следует по возможности избегать, поскольку они оставляют пользователей открытыми для слежки и взлома злонамеренными третьими лицами. Таким образом, все данные в этом новом скрипте обрабатываются как переменные до самой последней минуты, когда результаты выводятся в виде текстового файла.

  6. Сам полученный файл хэшируется, а путь / хэш выводятся в терминале. Мне нравится делать снимки этих хешей с помощью старой камеры, чтобы убедиться, что файл результатов не был подделан, когда я обращаюсь к нему позже.

  7. Старые файлы результатов игнорируются в подсчете. Это облегчает сравнение результатов.

Вот пример вывода терминала при запуске моего скрипта:

kernelcrunch@ubuntu:/usr/src/linux-headers-4.13.0-16-generic$ sha256rec
======================================================================= 
sha256rec:         
=======================================================================        
Current Folder : /usr/src/linux-headers-4.13.0-16-generic   
Target Folder  : /usr/src/linux-headers-4.13.0-16-generic
Output File    : /home/kernelcrunch/000_sha256sum_recurs_linux-headers-4.13.0-16-generic_d_22-04-2018_t_02.17.txt


Seems you're currently in either a Read-Only system or a root owned directory as a regular user. You can find the hash results in your home folder.
f3ddb06212622c375c6bcc11bd629ce38f6c48b7474054ca6f569ded4b4af9d8  /home/kernelcrunch/000_sha256sum_recurs_linux-headers-4.13.0-16-generic_d_22-04-2018_t_02.17.txt
Operation Length: 10 Seconds.
=======================================================================
kernelcrunch@ubuntu:/usr/src/linux-headers-4.13.0-16-generic$ 

Вот фрагмент вывода, который можно найти в 000_sha256sum_recurs_linux-headers-4.13.0-16-generic_d_22-04-2018_t_02.17.txt:

79c3f378a42bd225642220cc1e4801deb35c046475bb069a96870ad773082805  ./.9491.d
2e336c69cde866c6f01a3495048d0ebc2871dd9c4cb5d647be029e0205d15ce6  ./.config
174f23ff7a7fba897bfb7cf17e9a501bcecacf7ef0c0d5cf030414c1e257d4e3  ./.config.old
389d83f546b250304a9a01bb3072ff79f9d9e380c8a2106cadbf714a872afe33  ./.missing-syscalls.d
035dc77da819101cb9889b4e515023dddd2c953f00d2653b87c6196a6560903e  ./Module.symvers
b28054d7995233e6d003ceb9ed119a0b3354f5ccf77b8d687fc0353ae3c5bfb8  ./arch/x86/include/generated/asm/.syscalls_32.h.cmd
01cf821170e3e6e592e36a96e8628377151c762ac2ee3210c96004bfaef22f5f  ./arch/x86/include/generated/asm/.syscalls_64.h.cmd
111efa83187c58a74a9b0170fd496b497b0682d109a7c240c17e2ffcc734f4f4  ./arch/x86/include/generated/asm/.unistd_32_ia32.h.cmd
fcba4e8abf9e95472c31708555db844ac43c87260fb0ba706b6f519404bf9aba  ./arch/x86/include/generated/asm/.unistd_64_x32.h.cmd
3264438a54cbf7e62b05d38a93c5df8fe4202ac782a5d83ed202cba9eee71139  ./arch/x86/include/generated/asm/.xen-hypercalls.h.cmd
4bd7a45837da7de379b87242efe562ce06bf9d8ab8f636c205bb5ef384c8f759  ./arch/x86/include/generated/asm/clkdev.h
0d96461abd23bbf2da522822948455413a345f9ef8ac7a7f81c6126584b3c964  ./arch/x86/include/generated/asm/dma-contiguous.h
b1a54c24a12ce2c0f283661121974436cdb09ae91822497458072f5f97447c5d  ./arch/x86/include/generated/asm/early_ioremap.h
dd864107295503e102ea339e0fd4496204c697bdd5c1b1a35864dfefe504a990  ./arch/x86/include/generated/asm/mcs_spinlock.h
782ce66804d000472b3c601978fa9bd98dcf3b2750d608c684dc52dd1aa0eb7e  ./arch/x86/include/generated/asm/mm-arch-hooks.h
cd9913197f90cd06e55b19be1e02746655b5e52e388f13ec29032294c2f75897  ./arch/x86/include/generated/asm/syscalls_32.h
758ce35908e8cfeec956f57a206d8064a83a49298e47d47b7e9a7d37b5d96d59  ./arch/x86/include/generated/asm/syscalls_64.h
1147ca3a8443d9ccbdf9cd1f4b9b633f0b77f0559b83ec5e4fa594eadb2548be  ./arch/x86/include/generated/asm/unistd_32_ia32.h
ca5223fbf8f03613a6b000e20eb275d9b8081c8059bc540481a303ce722d42f3  ./arch/x86/include/generated/asm/unistd_64_x32.h
31703052c0d2ab8fe14b4e5dfcc45fcbd5feb5016b0a729b6ba92caa52b069e2  ./arch/x86/include/generated/asm/xen-hypercalls.h
c085ff1b6e9d06faa3fc6a55f69f9065c54098d206827deec7fe0a59d316fc99  ./arch/x86/include/generated/uapi/asm/.unistd_32.h.cmd
7929c16d349845cebb9e303e0ff15f67d924cac42940d0f7271584f1346635fc  ./arch/x86/include/generated/uapi/asm/.unistd_64.h.cmd
9aa492c5a75f5547f8d1dc454bef78189b8f262d1c4b00323a577907f138a63e  ./arch/x86/include/generated/uapi/asm/.unistd_x32.h.cmd
f568e151bbbb5d51fd531604a4a5ca9f17004142cd38ce019f0d5c661d32e36b  ./arch/x86/include/generated/uapi/asm/unistd_32.h
c45cf378498aa06b808bb9ccf5c3c4518e26501667f06c907a385671c60f14ae  ./arch/x86/include/generated/uapi/asm/unistd_64.h
a0088d8d86d7fd96798faa32aa427ed87743d3a0db76605b153d5124845161e2  ./arch/x86/include/generated/uapi/asm/unistd_x32.h
e757eb6420dffa6b24b7aa38ca57e6d6f0bfa7d6f3ea23bbc08789c7e31d15fa  ./arch/x86/kernel/.asm-offsets.s.cmd
f9e703e4f148d370d445c2f8c95f4a1b1ccde28c149cff2db5067c949a63d542  ./arch/x86/kernel/asm-offsets.s
7971fb3e0cc3a3564302b9a3e1ad188d2a00b653189968bbc155d42c70ce6fbf  ./arch/x86/purgatory/.entry64.o.cmd
8352d79fe81d2cf694880f428e283d79fd4b498cea5a425644da25a9641be26b  ./arch/x86/purgatory/.kexec-purgatory.c.cmd
37f3edbee777e955ba3b402098cb6c07500cf9dc7e1d44737f772ac222e6eb3e  ./arch/x86/purgatory/.purgatory.o.cmd
bb8b895cbd2611b69e2f46c2565b4c2e63a85afb56cff946a555f2d277ee99b2  ./arch/x86/purgatory/.purgatory.ro.cmd
bcc2365c9d3d027f1469806eb4f77b0f3ede6eb0855ea0fcd28aa65884046a54  ./arch/x86/purgatory/.setup-x86_64.o.cmd
872229f334fdcc8562e31b9f6581008c1571ac91f12889cd0ff413590585155a  ./arch/x86/purgatory/.sha256.o.cmd
6fb0cbef120aadee282f7bc3b5ea2f912980f16712281f8f7b65901005194422  ./arch/x86/purgatory/.stack.o.cmd
cd1b61063ae3cf45ee0c58b2c55039f3eac5f67a5154726d288b4708c4d43deb  ./arch/x86/purgatory/.string.o.cmd
e5826f0216fd590972bbc8162dd175f87f9f7140c8101505d8ca5849c850ec91  ./arch/x86/purgatory/entry64.o

(это продолжается для других 7000+ строк, как это, но вы поняли идею)

МОНТАЖ

  1. Откройте терминал и введите следующие команды:

    cd /usr/bin
    sudo su
    echo '#!/bin/bash'> /usr/bin/sha256rec
    chmod +x /usr/bin/sha256rec
    touch /usr/bin/sha256rec
    nano /usr/bin/sha256rec
    
  2. В nano используйте Shif +Ctrl +v для вставки. Ctrl-O и Enter, чтобы сохранить. Ctr-X выходит. Вставьте туда мой скрипт:

(вставьте после #!/ Бен / Баш)

  #FUNCTIONS OR FUNCTYOU?
  function s_readonly { err=$(date +%s%N); cd "$1"; mkdir $err 2> /tmp/$err; rmdir $err 2>/dev/null; echo $(cat /tmp/$err|grep -i "Read-only file system"|wc -l);shred -n 0 -uz /tmp/$err; }
  function w_denied { echo $(err=$(date +%s%N); cd "$1"; mkdir $err 2> /tmp/$err; rmdir $err 2>/dev/null; cat /tmp/$err|grep -i "Permission denied"|wc -l;shred -n 0 -uz /tmp/$err); }
  function r_denied { echo $(err=$(date +%s%N); cd "$1" >/dev/null 2> /tmp/$err; find . >/dev/null 2>> /tmp/$err; cat /tmp/$err|grep -i "Permission denied"|wc -l;shred -n 0 -uz /tmp/$err); }
  function rando_name { rando=$(echo $(date +%s%N)|sha256sum|awk '{print $1}'); rando=${rando::$(shuf -i 30-77 -n 1)}; echo $rando;}
  function ms0 { ms0=$(($(date +%s%N)/1000000)); }; function mstot { echo $(($(($(date +%s%N)/1000000))-$ms0));}
  function s0 { s0=$(date +%s); }; function stot { echo $(($(date +%s)-$s0));}
  s0

  #CHECK IF A TARGET DIR WAS SPECIFIED (-t= or --target= switch)
  if [ ! -z "$1" ]; then arg1="$1"; arg1_3=${arg1::3}; arg1_9=${arg1::9};fi
  if [ "$arg1_3" = "-t=" -o "$arg1_9" = "--target=" ]; then 
    switch=$(echo $arg1|awk -F '=' '{print $1}')
    switch_chr=$((${#switch}+1))
    target=${arg1:$switch_chr}
    current=$(pwd)
    cd "$target"
    arg1="" #<- cancels the not path in the find line
  else
    current=$(pwd)
    target=$(pwd) 
  fi

  echo -e  "=======================================================================\
    \nsha256rec: \
          \n=======================================================================\
          \nCurrent Folder : $current \
    \nTarget Folder  : $target"

  #GETS DEFAULT_USER, ASSUME'S YOU'RE USER 1000, IF 1000 DOESN'T EXIST SEARCHES 999, THEN 1001, 1002
  default_user=$(awk -v val=1000 -F ":" '$3==val{print $1}' /etc/passwd)
  if [ -z "$default_user" ]; then default_user=$(awk -v val=999 -F ":" '$3==val{print $1}' /etc/passwd); fi
  if [ -z "$default_user" ]; then default_user=$(awk -v val=1001 -F ":" '$3==val{print $1}' /etc/passwd); fi
  if [ -z "$default_user" ]; then default_user=$(awk -v val=1002 -F ":" '$3==val{print $1}' /etc/passwd); fi

  if [ "$(users | wc -l)" = "1" ]; then USER=$(users|awk '{print $1}'); else USER=$default_user;fi #not perfect but meh...

  #running rando_name in this very specific spot between USER detection and Permission detection, some interfers somehow with detection functions... 
  #the rando function placed underneath the user detection is somehow turning c=$current from the dir path to whatever rando_name puts out.

  #FIGURE OUT WHERE TO PUT HASH LIST
  hash_file="000_sha256sum_recurs_${target##*/}_d_$(date +%d-%m-20%y)_t_$(date +%H.%M).txt"
  if [ $(s_readonly "$current") -gt 0 -o $(w_denied "$current") -gt 0 ]; then if [ "$(whoami)" != root ]; then dest="/home/$(whoami)";echo -e "Output File    : $dest/$hash_file\n\n";echo "Seems you're currently in either a Read-Only system or a root owned directory as a regular user. You can find the hash results in your home folder."; else dest="/home/$USER";echo -e "Output File    : $dest/$hash_file\n\n";echo "Seems you're currently a Read-Only system. You can find the hash results in $USER's home folder.";fi; else dest="$current";echo -e "Output File    : $dest/$hash_file\n\n";echo "Results will be saved here.";fi



  #CAN REGULAR USER ACCESS TARGET DIR? ARE ALL IT'S SUBDIRS READABLE?
  if [ $(r_denied "$target") -gt 0 ]; then sudo=sudo; echo "Some folder were not read-able as a regular user. User elevation will be required.";fi

  #PERFORM RECURSIVE HASHING
  command=$($sudo find . -type f -not -type l -not -path "$arg1"  -not -path "$2"  -not -path "$3" -not -path "$4"  -not -path "$5"  -not -path "$6" -not -path "$7"  -not -path "$8"  -not -path "$9" |grep -v "\./000_sha"|sort|awk "{print \"$sudo sha256sum \\\"\"\$0}"|awk '{print $0"\""}'|tr '\n' ';')
  eval $command > "$dest/$hash_file"

  sha256sum "$dest/$hash_file"
  echo "Operation Length: $(stot) Seconds."
  echo -e  "======================================================================="



  if [ "$target" != "$current" ]; then cd "$current";fi


  exit
  #||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
  #||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
  #||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
  #||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
  1. Когда вы выходите из nano, обязательно выйдите из повышенного статуса, введя:

    exit
    

ПОСЛЕДНИЕ МЫСЛИ

  1. Это будет работать только если у вас установлен bash. Я использовал синтакс для манипулирования подстрокой, который не работает с sh, dash, ksh или zsh. Вы по-прежнему можете использовать любые другие оболочки в качестве ежедневных драйверов, но необходимо установить bash.

  2. Выводимые списки можно сравнить с различными инструментами, такими как: (в терминале) diff, sdiff (и графический) diffuse, kdiff, winmerge.

  3. Мой файл сортирует вывод на основе пути, чтобы его было легче читать людям. Я заметил, что команда сортировки работает по-разному в разных дистрибутивах. Например, в одном дистрибутиве буквы CAPITAL имеют приоритет над не прописными буквами, а в другом - нет. Это влияет на порядок строк выходных файлов и может затруднить сравнение файлов. Это не должно вызывать проблем, если вы всегда используете скрипт в одном и том же дистрибутиве, но может возникнуть, если списки хэшей были созданы в двух разных средах. Это легко исправить, отсортировав хеш-файлы в дополнительное время, чтобы строки упорядочивались по хешу, а не по пути:

     cat 000_sha256sum_oldhashlist|sort> ./old
     cat 000_sha256sum_newhashlist|sort> ./new
     sha256sum ./old ./new; diff ./old ./new
    
4

ОБНОВЛЕНИЕ: Прошло несколько лет с тех пор, как я опубликовал этот ответ, и в то же время я переписал и улучшил сценарий, который я представил здесь несколько раз. Я решил опубликовать новый сценарий как новый ответ. Я очень рекомендую это по этому.

ВСТУПЛЕНИЕ

Я заметил, что порядок, в котором команда find выводит найденные элементы в каталоге, варьируется в пределах одинаковых каталогов на разных разделах. Если вы сравниваете хэши одного и того же каталога, вам не нужно об этом беспокоиться, но если вы получаете хэши, чтобы убедиться, что файлы не были пропущены или повреждены во время копирования, вам нужно добавить дополнительную строку для сортировка содержимого каталога и его элементов. Например, ответ Мэтью Бонсака довольно элегантный:

find ./path/to/directory/ -type f -print0  | xargs -0 sha1sum

Но если вы используете его для сравнения скопированного каталога с его оригиналом, вы отправите вывод в текстовый файл, который вы сравните с выводимым списком из другого каталога, используя Kompare или WinMerge, или просто получите хеши каждого списка. , Дело в том, что порядок, в котором инструмент поиска будет выводить содержимое, может варьироваться от одного каталога к другому, Kompare будет сигнализировать о многих различиях, поскольку хеши не были вычислены в том же порядке. Ничего страшного для небольших каталогов, но довольно раздражает, если вы имеете дело с 30000 файлами. Поэтому вы должны выполнить дополнительные шаги по сортировке выходных данных, чтобы упростить сравнение списков хеш-функций между двумя каталогами.

find ./path/to/directory/ -type f -print0  | xargs -0 sha1sum > sha1sum_list_unsorted.txt
sort sha1sum_list_unsorted.txt > sha1sum_list_sorted.txt

Это отсортировало бы выходные данные так, чтобы файлы с одинаковым хешем находились в одинаковых строках при запуске разностной программы (при условии, что в новом каталоге нет файлов).

И НА СЦЕНАРИЙ ...

Вот сценарий, который я написал. Он выполняет те же действия, что и ответ find/xarg, но сортирует файлы перед получением sha1sum (сохраняя их в том же каталоге). Первая строка скрипта рекурсивно находит все файлы в каталоге. Следующий сортирует результаты в алфавитном порядке. Следующие два, берет отсортированный контент и добавляет к файлам в отсортированном списке sha1sum и кавычки, создавая большой скрипт оболочки, который вычисляет хэш каждого файла по одному и выводит его в content_sha1sum.txt.

#!/bin/bash
find . -type f > content.txt
sort content.txt > content_sorted.txt
awk '{print "sha1sum \""$0}' content_sorted.txt > temp.txt
awk '{print $0"\""}' temp.txt > get_sha1.sh
chmod +x get_sha1.sh
./get_sha1.sh > content_sha1sum.txt
rm content.txt
rm content_sorted.txt
rm temp.txt
rm get_sha1.sh
xdg-open content_sha1sum.txt

Надеюсь это поможет.

1

Быстрое, надежное и портативное решение

В отличие от некоторых других решений, использующих tar , приведенное ниже решение работает на любой машине, на которой установлены стандартные утилиты Unix, и быстрее, чем все другие решения, распараллеливая контрольные суммы:

find . -type f | xargs -d'\n' -P0 -n1 md5sum | sort -k 2 | md5sum

Поскольку в конце используется сортировка, прогресс в реальном времени отсутствует, так что просто дайте команде выполнить.

Вот что делают аргументы:

  • find . -type f находит все файлы в текущем каталоге и его подкаталогах
  • xargs -d'\n' разделяет вывод команды find на строки (если вы ожидаете, что в них будут файлы с символами новой строки, выполните обычную find -print0 | xargs -0)
  • -P0 n1 запускает md5sum в параллельных процессах, используя максимальное количество процессов, поддерживаемых машиной (многоядерный!)
  • sort -k 2 сортирует по второму полю вывода md5sum , который является полным путем к каждому файлу (первым является MD5)
  • последняя md5sum вычисляет контрольную сумму списка контрольных сумм файлов, так что вы получаете контрольную сумму всего каталога в одной строке, которую вы можете легко сравнить визуально через окна терминала

Прежде чем сказать, что "MD5 был скомпрометирован", имейте в виду, какая у вас модель угрозы. Вы пытаетесь убедиться, что файлы, скопированные с другого хоста или диска, остались нетронутыми? Тогда MD5 более чем достаточно, потому что вероятность повреждения файла при передаче, но имеющего тот же MD5, равна нулю. Но если вы боитесь, что злоумышленник успеет заменить файл другим на контрольную сумму, то используйте sha256sum . Недостатком является то, что функции SHA работают медленнее, чем MD5 .

Подробный прогресс в реальном времени

Наконец, если вы хотите видеть прогресс в реальном времени, измените конвейер, чтобы использовать временный файл для контрольных сумм:

find . -type f | xargs -d\\n -P0 -n1 md5sum | tee /tmp/sums && sort -k 2 /tmp/sums | md5sum

(Обратите внимание, что перемещение sort сразу после find не сработает, потому что xargs -P0 распараллеливает md5sum , и результаты могут быть получены не по порядку.)

Эта версия команды также позволяет вам различать два файла /tmp/sums (не забудьте переименовать второй, если он находится на том же компьютере) и посмотреть, какие файлы различаются.

1

Кажется, это работает для меня:

find . \( -not -name . \) -type f -exec cat {} + | sha1sum

РЕДАКТИРОВАТЬ: это будет только sha1sum всех файлов, содержащихся в дереве каталогов. Если имя каталога было изменено, оно не будет поймано. Может быть что-то вроде:

find . -exec sha1sum {} + 2>&1 | sha1sum

Сделал бы это. Примерно такой же ответ, как и у другого

1

Другой трюк может заключаться в использовании tar для хэширования содержимого файла и метаданных:

tar -cf - ./path/to/directory | sha1sum
0

на основании предыдущего ответа:

find ./path/to/directory -print0 | LC_ALL=C sort --zero-terminated | tar --create --no-recursion --null --files-from /dev/stdin --file /dev/stdout --verbose --numeric-owner | sha1sum

  • стабильный сорт
  • числовой владелец и идентификатор группы
  • подробный прогресс
  • безопасное имя файла
0

Вместо того, чтобы иметь ОДИН огромный файл, содержащий всю хешированную информацию, я искал способ сделать файл в каждой папке дерева. Я черпал вдохновение из комментариев здесь. Мой немного сложнее, чем то, что размещено здесь. Я использую ротацию файлов, но это наименее сложно для новых игроков. Эта версия будет перезаписывать старые контрольные суммы новыми. Может быть полезно сохранить 2-3 версии в зависимости от того, как часто вы запускаете его, и от вашей потребности в «глубине».

[user@host bin]$ cat mkshaindir 
#!/bin/dash
cd $1
sha512sum * >.sha512sum

[user@host bin]$ find /var/tmp -type d -print0 | xargs -0 -i  mkshaindir  {}

Обратите внимание, что mkshaindir, для моих целей, является отдельным компонентом, потому что мне может понадобиться создать хэш файлов в новой папке или в файле, который был недавно изменен. Все это может быть объединено в один скрипт, если это необходимо.

Остальное оставлено в качестве упражнения для читателя.

0

@allquixotic не генерирует одинаковые хэши на разных машинах, что не поможет нам проверить и иметь согласованные хэши.

Следующую строку find . -type f \( -exec md5sum "$PWD"/{} \; \) возвращает следующий вывод:

d41d8cd98f00b204e9800998ecf8427e  /home/helloWorld.c
24811012be8faa36c8f487bbaaadeb71  /home/helloMars.c

Следовательно, путь будет разным на разных машинах. awk '{print $1}' поможет нам получить первый столбец, в котором есть только хэш файлов. Позже нам нужно отсортировать те хэши, где порядок может отличаться на разных машинах, что также может привести к тому, что у нас будут разные хэши, если существует более двух файлов.


Решение:

Для Mac:

find ./path/to/directory/ -type f \( -exec md5 -q  "$PWD"/{} \; \) | awk '{print $1}' | sort | md5

Для Linux:

find ./path/to/directory/ -type f \( -exec md5sum "$PWD"/{} \; \) | awk '{print $1}' | sort | md5sum | awk '{print $1}'

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .