sha1sum dla katalogu katalogów

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

powyższe zostało opublikowane jako sposób na obliczenie sumy całkowitej katalogu zawierającego pliki. To polecenie kończy się niepowodzeniem, jeśli katalog zawiera więcej katalogów. Czy istnieje sposób, aby rekurencyjnie obliczać sumę całkowitą katalogu katalogów uniwersalnie (bez niestandardowego dopasowywania algorytmu do konkretnego katalogu)?

Ocasta Eshu
źródło

Odpowiedzi:

14

Dzięki temu postowi SO -

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

Ostrzeżenie: ten kod nie został przetestowany ! Edytuj to pytanie, jeśli jest nieprawidłowe i możesz je naprawić; Zatwierdzę twoją edycję.

allquixotic
źródło
Przepraszam; Nie mogłem się oprzeć! ;-) Rekurencja jest fajna. Oczywiście jest sposób. Napiszę teraz właściwą odpowiedź.
allquixotic
3
Nie spowoduje to wygenerowania tego samego skrótu dla dokładnie tych samych folderów na różnych komputerach, ponieważ dane wyjściowe zawierają również <skrót> i <ścieżkę pliku>, która ścieżka pliku jest inna na różnych komputerach i powoduje różne skróty na różnych komputerach. Prawidłowa linia powinna być podobna do find . -type f \( -exec sha1sum "$PWD"/{} \; \) | awk '{print $1}' | sort | sha1sum@allquixotic
alper
1
Ponadto należy uporządkować skróty plików, co spowoduje także różne skróty, jeśli kolejność sortowania jest różna na różnych komputerach.
alper
40

Ogólnie podoba mi się wzorzec „znajdź | xargs”:

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

Musisz użyć „-print0” i „-0”, na wypadek, gdyby w nazwach plików były spacje.

Jest to jednak bardzo podobne do wzorca „find -exec cmd {}”.

Zobacz dyskusję porównującą dwa wzorce tutaj: https://stackoverflow.com/questions/896808/find-exec-cmd-vs-xargs

Matthew Bohnsack
źródło
Twoja odpowiedź zwraca tylko skrót plików. Hash folderu należy uzyskać za pomocą find . -type f -print0 | xargs -0 sha1sum | awk '{print $1}' | sha1sum.
alper
5

AKTUALIZACJA: Minęło kilka lat, odkąd opublikowałem tę odpowiedź, a tymczasem przepisałem i poprawiłem skrypt, który tutaj przedstawiłem kilka razy. Postanowiłem ponownie opublikować nowy skrypt jako zupełnie nową odpowiedź. Gorąco poleciłbym to nad tym.

WPROWADZENIE

Zauważyłem, że kolejność, w jakiej komenda find wyświetla znalezione elementy w katalogu, zmienia się w identycznych katalogach na różnych partycjach. Jeśli porównujesz skróty tego samego katalogu, nie musisz się tym martwić, ale jeśli otrzymujesz skróty, aby upewnić się, że żadne pliki nie zostały pominięte lub uszkodzone podczas kopiowania, musisz dołączyć dodatkowy wiersz sortowanie zawartości katalogu i jego elementów. Na przykład odpowiedź Matthew Bohnsacka jest dość elegancka:

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

Ale jeśli używasz go do porównywania skopiowanego katalogu do jego oryginalnego, wyślesz dane wyjściowe do pliku txt, który porównasz z listą wyjściową z innego katalogu za pomocą Kompare lub WinMerge lub po prostu uzyskując skróty każdego lis . Chodzi o to, że ponieważ kolejność wyświetlania przez narzędzie wyszukiwania zawartości może się różnić w zależności od katalogu, Kompare zasygnalizuje wiele różnic, ponieważ skróty nie zostały obliczone w tej samej kolejności. Nie jest to wielka sprawa dla małych katalogów, ale dość denerwująca, jeśli masz do czynienia z 30000 plików. Dlatego wykonałeś dodatkowe kroki w sortowaniu danych wyjściowych, aby ułatwić porównanie list skrótów między dwoma katalogami.

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

Spowodowałoby to sortowanie danych wyjściowych, dzięki czemu pliki z tym samym hashem będą znajdować się w tych samych wierszach podczas uruchamiania programu różnicującego (pod warunkiem, że w nowym katalogu nie brakuje żadnych plików).

I NA PISMO ...

Oto skrypt, który napisałem. Robi to samo co odpowiedź find / xarg, ale sortuje pliki przed pobraniem sha1sum (utrzymując je w tym samym katalogu). W pierwszym wierszu skryptu rekursywnie znajdują się wszystkie pliki w katalogu. Następny sortuje wyniki alfabetycznie. Następne dwa pobierają posortowaną zawartość i dołączają sha1sum i cudzysłowy do plików na posortowanej liście, tworząc duży skrypt powłoki, który oblicza skrót każdego pliku, pojedynczo i wysyła go do 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

Mam nadzieję że to pomoże.

thebunnyrules
źródło
Gdy łączna długość wszystkich nazw plików mieści się w wierszu polecenia, przesyłanie strumieniowe przez sort -z( --zero-terminated) jest łatwiejsze niż bałagan z wieloma plikami.
Anton Samsonov,
@AntonSamsonov To naprawdę stary skrypt, uczyłem się wtedy skryptowania. Od tego czasu przepisałem to wiele razy. W odniesieniu do twojego komentarza, co robi zakończenie zerowania podczas sortowania: Przeczytałem stronę podręcznika systemowego. Mówią, że zero kończy się bajtem zero na końcu linii zamiast nowej linii. Co to osiąga?
thebunnyrules
Opublikowałem aktualizację tego skryptu jako oddzielną odpowiedź tutaj: superuser.com/questions/458326/…
thebunnyrules
4

WPROWADZENIE

Kilka lat temu napisałem i przedstawiłem (w tym wątku) skrypt, który może sprawdzić sygnatury hash wszystkich pojedynczych plików w bieżącej strukturze katalogów i wyprowadzić je jako listę w pliku tekstowym.

Od tego czasu kilkakrotnie dopracowałem tę formułę. Postanowiłem ponownie opublikować mój nowy i ulepszony skrypt tutaj jako osobną odpowiedź. Jest napisany dla sha256, ale każdy, kto nadal chce używać sha1, może przeprowadzić proste wyszukiwanie i zastąpić w gedit, aby zamienić sha256 na sha1. Osobiście nie używałem sha1 od kilku lat i nie polecałbym go, ponieważ stał się przestarzały, a Google zademonstrował, jak można go złamać .

Oto, co robi mój nowy skrypt:

  1. Możesz po prostu użyć skryptu, przechodząc do katalogu, który chcesz haszować i wprowadzając:

    sha256rec

    Alternatywnie możesz wywołać ten skrypt z innego katalogu, wykonując:

    sha256rec "/path/to/target/directory/you/want/hash"
  2. Skrypt wykryje, czy masz uprawnienia do zapisu w bieżącym katalogu. Jeśli to zrobisz, wyniki zostaną zapisane w bieżącym katalogu. Jeśli nie masz uprawnień do zapisu lub jeśli twój bieżący katalog znajduje się w systemie tylko do odczytu (takim jak cdrom), wyniki zostaną zapisane w katalogu osobistym bieżącego użytkownika.

  3. Skrypt wykryje, czy niektóre podkatalogi nie są dostępne przy obecnych uprawnieniach użytkownika. Jeśli wszystkie są czytelne, wówczas nie następuje podniesienie uprawnień, jeśli nie są, wówczas uprawnienia użytkownika są podnoszone do uprawnień root.

  4. Znajdź służy do wyszukiwania wszystkich plików w bieżącej strukturze katalogów (w tym wszystkich podkatalogów). Sortowanie służy do upewnienia się, że wyniki są wyprowadzane alfabetycznie. Powstała lista przechodzi sha256sum i jest wyprowadzana do pliku tekstowego.

  5. Od czasu napisania starego skryptu przyjąłem filozofię projektowania, że ​​pliki tymczasowe są złe i należy ich unikać, gdy jest to możliwe, ponieważ pozostawiają one użytkowników otwartymi na szpiegowanie i manipulowanie przez złośliwe strony trzecie. Tak więc wszystkie dane w tym nowym skrypcie są przetwarzane jako zmienne do ostatniej chwili, gdy wyniki są wyprowadzane jako plik tekstowy.

  6. Sam plik wynikowy jest mieszany, a ścieżka / skrót są wyprowadzane w terminalu. Lubię robić zdjęcia tych skrótów starym aparatem offline w trybie offline, aby mieć pewność, że plik wyników nie zostanie zmieniony, gdy odwołam się do niego w późniejszym terminie.

  7. Stare pliki wyników są ignorowane w podsumowaniu. Ułatwia to porównywanie wyników.

Oto przykład danych wyjściowych terminala podczas uruchamiania mojego skryptu:

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$ 

Oto fragment wyniku, który można znaleźć w 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

(to trwa przez kolejne 7000+ linii, ale masz pomysł)

INSTALACJA

  1. Otwórz terminal i wprowadź następujące polecenia:

    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. W nano użyj Shif + Ctrl + v, aby wkleić. Ctrl-O i Enter, aby zapisać. Ctr-X wychodzi. Wklej tam mój skrypt:

(wklej po #! / 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. Po wyjściu z nano należy wyjść z podwyższonego statusu, wprowadzając:

    exit

KOŃCOWE PRZEMYŚLENIA

  1. Działa to tylko wtedy, gdy masz zainstalowany bash. Użyłem składni do manipulacji podciągami, która nie działa z sh, dash, ksh lub zsh. Nadal możesz używać innych powłok jako codziennych sterowników, ale bash musi zostać zainstalowany.

  2. Listy wyników można porównać z różnymi narzędziami, takimi jak: (w terminalu) diff, sdiff (i graficzny) diffuse, kdiff, winmerge.

  3. Mój plik sortuje dane wyjściowe na podstawie ścieżki, aby ułatwić czytanie ludziom. Zauważyłem, że polecenie sortowania działa inaczej w różnych dystrybucjach. Na przykład, w jednej dystrybucji litery KAPITALOWE miały pierwszeństwo przed literami bez wielkich liter, aw drugiej nie. Wpływa to na kolejność plików wyjściowych i może utrudniać porównywanie plików. Nie powinno to powodować żadnych problemów, jeśli zawsze używasz skryptu w tej samej dystrybucji, ale może, jeśli listy skrótów zostały wygenerowane w dwóch różnych środowiskach. Łatwo temu zaradzić, sortując pliki skrótu dodatkowo, aby linie były uporządkowane według skrótu zamiast ścieżki:

     cat 000_sha256sum_oldhashlist|sort> ./old
     cat 000_sha256sum_newhashlist|sort> ./new
     sha256sum ./old ./new; diff ./old ./new
thebunnyrules
źródło
Bardziej solidna linia shebang byłaby #!/usr/bin/env bash- znajdzie Bash również w innych katalogach, ponieważ ten ostatni może być zainstalowany na przykład w / usr / bin zamiast / bin , tymczasem env ma tendencję do bycia w / usr / bin przez cały czas o ile zauważyłem. Warto również zauważyć, że ponieważ potrzebujesz Bash, możesz użyć [[ blah-blah ]]wyrażenia warunkowego z dwoma nawiasami zamiast bardziej ogólnego [ blah-blah ]wariantu z jednym nawiasiem.
Anton Samsonov
Dzięki za wskazówki. Właśnie skończyłem przeglądać [[warunkowe. Wyglądają naprawdę przydatnie.
thebunnyrules,
Obawa przed naruszeniem SHA1 nie ma tak naprawdę zastosowania w przypadku porównywania plików po skopiowaniu w celu sprawdzenia integralności. Szanse na to, że plik zostanie uszkodzony podczas przesyłania, ale nadal ma ten sam SHA1, są praktycznie zerowe. Jeśli podejrzewasz, że osoba atakująca mogła mieć wystarczająco dużo czasu, aby wygenerować inny plik z kolidującym SHA1, użyj SHA256, ale w typowym przypadku kopiowania plików jest to nadmierne i wolniejsze niż SHA1 lub MD5 .
Dan Dascalescu
Twój własny argument może być wykorzystany przeciwko sobie. Jeśli martwisz się o normalne (niezwiązane z atakiem) uszkodzenie, to sam sha1 to przesada. Możesz uzyskać szybsze wyniki za pomocą md5 / crc32. W obu sytuacjach (wykrywanie sabotażu lub uszkodzenie) sha1 nie jest dobrym dopasowaniem. Osobiście używam tych list skrótów w obu scenariuszach i nie zauważyłem żadnego zauważalnego spadku wydajności od czasu aktualizacji do wersji sha256, ale nie mam też dużego serwera. Jak powiedziałem w odpowiedzi, możesz dowolnie używać skrótu, zastępując moje polecenie sha256sum tym, którego chcesz: sha1sum, md5sum, b2sum, crc32 ...
thebunnyrules
1

Wydaje mi się, że to działa:

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

EDYCJA: spowoduje to tylko sumowanie wszystkich plików zawartych w drzewie katalogów. Jeśli nazwa katalogu zostanie zmieniona, to nie złapie go. Może coś takiego:

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

Zrobiłbym to. O tej samej odpowiedzi, co druga

d0c_s4vage
źródło
1

Inną sztuczką może być użycie tar do mieszania zawartości pliku i metadanych:

tar -cf - ./path/to/directory | sha1sum
kvz
źródło
szkoda, że ​​mam tylko jeden głos
166_MMX
1
To nie działa. tar zawiera znacznik czasu dla niektórych systemów operacyjnych (takich jak OSX), a sha1sum będzie inny dla każdego uruchomienia.
srossross 28.09.17
Co powiedział @srossross. Dodatkowo, jeśli masz różne wersje tar na dwóch hostach, wyniki będą inne.
Dan Dascalescu
1

Szybkie, solidne i przenośne rozwiązanie

W przeciwieństwie do niektórych innych rozwiązań tar, poniższe rozwiązanie działa na każdym komputerze, który ma standardowe narzędzia Uniksa i jest szybsze niż wszystkie inne rozwiązania poprzez równoległe sprawdzanie sum:

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

Ponieważ używa on sortowania na końcu, nie ma postępu w czasie rzeczywistym, więc po prostu uruchom polecenie.

Oto, co robią argumenty:

  • find . -type f znajduje wszystkie pliki w bieżącym katalogu i jego podkatalogach
  • xargs -d'\n'dzieli wyjście find na linie (jeśli spodziewasz się, że będziesz mieć pliki z nowymi liniami, to wykonaj zwykłe czynności find -print0 | xargs -0)
  • -P0 n1działa md5sumw równoległych procesach, wykorzystując maksymalną liczbę procesów obsługiwanych przez maszynę (wielordzeniowy!)
  • sort -k 2sortuje według drugiego pola md5sumwyjściowego, które jest pełną ścieżką do każdego pliku (pierwszym jest MD5)
  • końcowy md5sumoblicza sumę kontrolną listy sum kontrolnych plików, dzięki czemu otrzymujesz sumę kontrolną całego katalogu w jednym wierszu, którą możesz łatwo porównać wizualnie w oknach terminala

Zanim powiesz, że „MD5 zostało przejęte”, pamiętaj, jaki jest twój model zagrożenia. Czy chcesz się upewnić, że pliki skopiowane z innego hosta lub dysku dotarły nienaruszone? Wtedy MD5 jest więcej niż wystarczające, ponieważ szanse na uszkodzenie pliku podczas przesyłania, ale z tym samym MD5 są zerowe. Ale jeśli boisz się, że atakujący będzie miał czas na zastąpienie pliku innym plikiem z kolidującą sumą kontrolną, użyj sha256sum. Minusem jest to, że funkcje SHA są wolniejsze niż MD5 .

Pełne postępy w czasie rzeczywistym

Wreszcie, jeśli chcesz zobaczyć postęp w czasie rzeczywistym, zmodyfikuj potok, aby używał pliku tymczasowego dla sum kontrolnych:

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

(Pamiętaj, że przeniesienie sortzaraz po findnie zadziałałoby, ponieważ działa xargs -P0równolegle md5sum, a wyniki mogą pojawiać się poza kolejnością).

Ta wersja polecenia umożliwia także różnicowanie dwóch /tmp/sumsplików (pamiętaj, aby zmienić nazwę drugiego pliku, jeśli jest on na tym samym komputerze) i zobaczyć, które pliki się różnią.

Dan Dascalescu
źródło
0

Zamiast JEDEN ogromnego pliku zawierającego wszystkie zaszyfrowane informacje szukałem sposobu na utworzenie pliku w każdym folderze drzewa. Inspirację czerpałem z komentarzy tutaj. Mój jest nieco bardziej złożony niż to, co tu zamieszczono. Używam rotacji plików, ale jest to najmniej skomplikowane dla nowych odtwarzaczy. Ta wersja spowoduje zastąpienie starych sum czeków nowymi. Dobrze jest zachować 2-3 wersje, w zależności od tego, jak często go uruchamiasz i potrzeby „głębokości”.

[użytkownik @ host bin] $ cat mkshaindir 
#! / bin / dash
cd 1 USD
sha512sum *> .sha512sum

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

Zauważ, że mkshaindir, dla moich celów, jest osobnym komponentem, ponieważ może zaistnieć potrzeba stworzenia skrótu plików w nowym folderze lub w niedawno zmienionym folderze. W razie potrzeby można to wszystko połączyć w jeden skrypt.

Resztę pozostawia się jako ćwiczenie dla czytelnika.

Chris
źródło
0

na podstawie poprzedniej odpowiedzi :

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

  • stabilny rodzaj
  • numeryczny właściciel i identyfikator grupy
  • pełny postęp
  • nazwa pliku jest bezpieczna
166_MMX
źródło
Nie działało to na skopiowanym katalogu zawierającym tylko jeden plik i podejrzewam, że było tak, ponieważ uruchomiłem nieco starszą wersję tar (1.28) na zdalnym hoście, w porównaniu z 1.29 na hoście lokalnym. Niestety, tar 1.29 nie został backportowany na Xenial.
Dan Dascalescu
0

@allquixoticOdpowiedź nie generuje takich samych skrótów na różnych komputerach, co nie pomoże nam zweryfikować i mieć spójnych skrótów.

Następujący wiersz find . -type f \( -exec md5sum "$PWD"/{} \; \)zwraca następujące dane wyjściowe:

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

Dlatego ścieżka byłaby inna na różnych komputerach. awk '{print $1}'pomoże nam uzyskać pierwszą kolumnę, która ma tylko skrót plików. Później musimy posortować te skróty, w których kolejność może być różna na różnych komputerach, co może również powodować, że będziemy mieć różne skróty, jeśli są więcej niż dwa pliki.


Rozwiązanie:

Dla Maca:

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

W systemie Linux:

find ./path/to/directory/ -type f \( -exec md5sum "$PWD"/{} \; \) | awk '{print $1}' | sort | md5sum | awk '{print $1}'
Alper
źródło