sha1sum для каталога каталогов


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

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

Ответы:


14

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

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

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


Сожалею; Я не мог устоять! ;-) Рекурсия это весело. Конечно, есть способ. Я напишу правильный ответ сейчас.
allquixotic

3
Это не будет генерировать один и тот же хеш для одинаковых папок на разных компьютерах, потому что выходные данные также содержат <hash> и <путь к файлу>, путь к файлу которых различен на разных компьютерах и вызывает различное хеширование на разных компьютерах. Правильная линия должна быть как find . -type f \( -exec sha1sum "$PWD"/{} \; \) | awk '{print $1}' | sort | sha1sum@allquixotic
Alper

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

40

Мне обычно нравится шаблон "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


Ваш ответ возвращает только хэш файлов. Хеш папки должен быть получен с помощью find . -type f -print0 | xargs -0 sha1sum | awk '{print $1}' | sha1sum.
Alper

5

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

ВВЕДЕНИЕ

Я заметил, что порядок, в котором команда 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

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


Когда общая длина всех имен файлов вписывается в командную строку, прохождение через sort -z( --zero-terminated) легче, чем возиться с кучей файлов.
Антон Самсонов

@AntonSamsonov Это действительно старый сценарий, в то время я только изучал сценарии. С тех пор я переписывал это целую кучу раз. Что касается вашего комментария, что делает нулевое завершение при сортировке: я прочитал справочную страницу сортировки. Они говорят, что завершающий ноль вставляет нулевой байт в конце строки вместо новой строки. Что это делает?
thebunnyrules

Я разместил обновление этого скрипта в качестве отдельного ответа здесь: superuser.com/questions/458326/…
thebunnyrules,

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 выходит. Вставьте туда мой скрипт:

(вставьте после #! / bin / bash)

  #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

Более надежная притон линия будет #!/usr/bin/env bash- это будет найти Bash в других каталогах , как хорошо, так как последний может быть установлен в / USR / бен вместо / bin , например, тем временем окр имеет тенденцию быть в / USR / бен во все времена насколько я заметил. Также стоит отметить, что, поскольку вам требуется Bash, вы можете использовать [[ blah-blah ]]условное выражение с двумя скобками вместо более общего [ blah-blah ]варианта с одной скобкой.
Антон Самсонов

Спасибо за указатели. Я только что закончил искать [[условные выражения. Они выглядят действительно полезными.
thebunnyrules

Опасение, что SHA1 будет скомпрометирован, на самом деле неприменимо в случае сравнения файлов после копирования для проверки целостности. Вероятность повреждения файла при передаче, но с тем же SHA1, практически равна нулю. Если вы подозреваете, что у злоумышленника могло быть достаточно времени для создания другого файла с конфликтующим SHA1, используйте SHA256, но для типичного случая копирования файлов это избыточно и медленнее, чем SHA1 или MD5 .
Дан Даскалеску

Ваш собственный аргумент может быть использован против самого себя. Если вас беспокоит нормальное (не связанное с атакой) повреждение, то сам sha1 является излишним. Вы можете получить более быстрые результаты, используя md5 / crc32. В любой ситуации (обнаружение взлома или повреждение) sha1 не подходит. Лично я использую эти хэш-списки для обоих сценариев и не заметил какого-либо ощутимого снижения производительности с тех пор, как я обновился до sha256, но я также не использую мегасервер. Как я уже сказал в ответе, вы можете использовать любой хеш, который хотите, заменив мою команду sha256sum той, которую вы хотите: sha1sum, md5sum, b2sum, crc32 ...
thebunnyrules

1

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

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

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

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

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


1

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

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


1
Это не работает. tar включает временную метку для некоторых ОС (например, OSX), и sha1sum будет отличаться при каждом запуске.
Сроссросс

Что сказал @srossross. Кроме того, если у вас есть разные версии tar на двух хостах, результаты будут разными.
Дан Даскалеску

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)
  • final 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файла (не забудьте переименовать второй, если он находится на одном компьютере) и посмотреть, какие файлы различаются.


0

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

[user @ host bin] $ cat mkshaindir 
#! / Bin / тир
CD $ 1
sha512sum *> .sha512sum

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

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

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


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

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

Это не сработало на скопированном каталоге, содержащем только один файл, и я подозреваю, что это произошло потому, что я запускал немного более старую версию tar (1.28) на удаленном хосте, а не 1.29 на локальном хосте. К сожалению, смола 1,29 не портированная на дружественном.
Дан Даскалеску

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}'
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.