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


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

вище було розміщено як спосіб обчислення sha1sum каталогу, який містить файли. Ця команда не працює, якщо каталог містить більше каталогів. Чи є спосіб рекурсивно обчислити sha1sum каталогу каталогів універсально (без спеціального пристосування алгоритму до конкретного каталогу, про який йде мова)?

Відповіді:


14

Завдяки цій публікації SO -

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

Попередження: Цей код не перевірений ! Відредагуйте це питання, якщо воно неправильне, і ви можете його виправити; Я схвалюю вашу редакцію.


Вибачте; Я не втримався! ;-) Рекурсія - це весело. Звичайно, є спосіб. Я зараз напишу правильну відповідь.
allquixotic

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

1
На додаток до цього, хеші файлів повинні бути впорядковані, що також спричинить різні хеші, якщо порядок сортування різний на різних машинах.
Альпер

40

Я, як правило, люблю шаблон «знайти | 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.
альпер

5

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

ВСТУП

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

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

Але якщо ви використовуєте його для порівняння скопійованого каталогу з оригінальним, ви надішлите вихід у файл txt, який ви порівняєте з виведеним списком з іншого каталогу за допомогою 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 (зберігаючи їх у тому самому каталозі). Перший рядок сценарію знаходить усі файли в каталозі рекурсивно. Наступний сортує результати за алфавітом. Наступні два дістає відсортований вміст і додає до файлів у відсортованому списку ша1сум та лапки, створюючи великий скрипт оболонки, який обчислює хеш кожного файлу, по одному та виводить його у 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. Сценарій виявить, якщо деякі з підкаталогів недоступні при поточних правах користувача. Якщо всі читаються, то привілей користувача не відбувається, якщо їх немає, тоді користувацькі привілеї підняті до кореня.

  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. Для наклеювання використовуйте 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. Коли ви виходите з нано, не забудьте вийти з підвищеного статусу, ввівши:

    exit

ЗАКЛЮЧНІ МИСЛИ

  1. Це буде працювати лише в тому випадку, коли ви встановили bash. Я використав деякий syntax для маніпулювання підрядками, який не працює з sh, dash, ksh або zsh. Ви все ще можете використовувати будь-які інші оболонки як щоденні драйвери, але bash потрібно встановити.

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

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

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

Більш міцною лінією shebang було б #!/usr/bin/env bash- вона знайде Bash і в інших каталогах, оскільки останні можуть бути встановлені в / usr / bin, а не / bin , наприклад, тим часом env має тенденцію знаходитись у / usr / bin у будь-який час наскільки я помітив. Варто також зазначити, що, оскільки вам потрібен 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

EDIT: це лише sha1sum всі файли, що містяться в дереві каталогів. Якщо ім'я каталогу було змінено, це не зачепить його. Можливо, щось на кшталт:

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

Зробив би це. Приблизно така ж відповідь, як і інша


1

Іншим фокусом може бути використання tar для хешування вмісту файлу та метаданих:

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

шкода, що у мене є лише один голос
166_MMX

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

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


0

Замість того, щоб мати ОГРОМНИЙ величезний файл, що містить всю хешовану інформацію, я шукав спосіб зробити файл у кожній папці дерева. Я взяв трохи натхнення з коментарів тут. Шахта трохи складніше, ніж те, що розміщено тут. Я використовую обертання файлів, але це найменш складний для нових гравців. Ця версія дозволить їй замінити старі чекові суми новими. Можливо, буде добре зберігати 2-3 версії залежно від того, наскільки часто ви її запускаєте та від необхідності «глибини».

[user @ host bin] $ cat mkshaindir 
#! / бін / тире
cd $ 1
sha512sum *> .sha512sum

[user @ host bin] $ find / var / tmp -тип 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.