sha1sum für ein Verzeichnis von Verzeichnissen


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

die oben wurde geschrieben als eine Möglichkeit , eine sha1sum eines Verzeichnisses zu berechnen , die Dateien enthält. Dieser Befehl schlägt fehl, wenn das Verzeichnis mehr Verzeichnisse enthält. Gibt es eine Möglichkeit, die sha1sum eines Verzeichnisses von Verzeichnissen universell zu berechnen (ohne einen Algorithmus an das betreffende Verzeichnis anzupassen)?

Antworten:


14

Dank dieser SO Post -

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

Achtung: Dieser Code ist ungetestet ! Bearbeiten Sie diese Frage, wenn sie falsch ist und Sie sie beheben können. Ich werde Ihre Bearbeitung genehmigen.


Es tut uns leid; Ich konnte nicht widerstehen! ;-) Rekursion macht Spaß. Natürlich gibt es einen Weg. Ich werde jetzt eine richtige Antwort aufschreiben.
Allquixotic

3
Hierbei wird nicht derselbe Hash für genau die gleichen Ordner auf den verschiedenen Computern generiert, da die Ausgabe auch <Hash> und <Dateipfad> enthält, deren Dateipfad auf verschiedenen Computern unterschiedlich ist und unterschiedliche Hashes auf verschiedenen Computern verursacht. Die richtige Zeile sollte wie find . -type f \( -exec sha1sum "$PWD"/{} \; \) | awk '{print $1}' | sort | sha1sum@allquixotic
alper

1
Darüber hinaus sollten Hashes von Dateien in der Reihenfolge angeordnet sein, die auch unterschiedliche Hashes verursachen, wenn die Sortierreihenfolge auf verschiedenen Computern unterschiedlich ist.
Alper

40

Im Allgemeinen gefällt mir das Muster "find | xargs" wie folgt:

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

Sie müssen "-print0" und "-0" verwenden, falls die Dateinamen Leerzeichen enthalten.

Dies ist jedoch dem Muster "find -exec cmd {}" sehr ähnlich.

Eine Diskussion zum Vergleichen der beiden Muster finden Sie hier: https://stackoverflow.com/questions/896808/find-exec-cmd-vs-xargs


Ihre Antwort gibt nur einen Hash der Dateien zurück. Hash des Ordners sollte mit ermittelt werden find . -type f -print0 | xargs -0 sha1sum | awk '{print $1}' | sha1sum.
Alper

5

UPDATE: Es ist ein paar Jahre her, seit ich diese Antwort gepostet habe, und in der Zwischenzeit habe ich das Skript, das ich hier mehrmals vorgestellt habe, umgeschrieben und verbessert. Ich habe beschlossen, das neue Skript als brandneue Antwort neu zu veröffentlichen. Ich kann es nur wärmstens empfehlen.

EINFÜHRUNG

Ich habe beobachtet, dass die Reihenfolge, in der der Befehl find die gefundenen Elemente in einem Verzeichnis ausgibt, innerhalb identischer Verzeichnisse auf verschiedenen Partitionen variiert. Wenn Sie die Hashes desselben Verzeichnisses vergleichen, müssen Sie sich darüber keine Gedanken machen. Wenn Sie jedoch die Hashes abrufen, um sicherzustellen, dass beim Kopieren keine Dateien übersehen oder beschädigt wurden, müssen Sie eine zusätzliche Zeile für hinzufügen Sortieren des Inhalts des Verzeichnisses und seiner Elemente. Die Antwort von Matthew Bohnsack ist zum Beispiel recht elegant:

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

Wenn Sie es jedoch verwenden, um ein kopiertes Verzeichnis mit dem Original zu vergleichen, senden Sie die Ausgabe an eine txt-Datei, die Sie mit Kompare oder WinMerge mit der ausgegebenen Liste aus dem anderen Verzeichnis vergleichen oder indem Sie einfach die Hashes der einzelnen lis abrufen . Die Sache ist, da die Reihenfolge, in der das Find-Tool den Inhalt ausgibt, von einem Verzeichnis zum anderen variieren kann, signalisiert Kompare viele Unterschiede, da die Hashes nicht in derselben Reihenfolge berechnet wurden. Keine große Sache für kleine Verzeichnisse, aber ziemlich ärgerlich, wenn Sie mit 30000 Dateien arbeiten. Daher müssen Sie die Ausgabe in zusätzlichen Schritten sortieren, um den Vergleich der Hash-Listen zwischen den beiden Verzeichnissen zu vereinfachen.

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

Dies würde die Ausgabe so sortieren, dass sich Dateien mit demselben Hash in denselben Zeilen befinden, wenn das differenzierende Programm ausgeführt wird (vorausgesetzt, das neue Verzeichnis fehlt nicht).

UND AUF DAS SCRIPT ...

Hier ist ein Skript, das ich geschrieben habe. Es macht das Gleiche wie die Antwort find / xarg, sortiert jedoch die Dateien, bevor die sha1sum abgerufen wird (und speichert sie im selben Verzeichnis). Die erste Zeile des Skripts findet alle Dateien im Verzeichnis rekursiv. Der nächste sortiert die Ergebnisse alphabetisch. In den beiden folgenden Schritten wird der sortierte Inhalt verwendet, und den Dateien in der sortierten Liste werden eine sha1sum und Anführungszeichen angehängt. Dabei wird ein großes Shell-Skript erstellt, das jeden Datei-Hash nacheinander berechnet und an content_sha1sum.txt ausgibt.

#!/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

Hoffe das hilft.


Wenn die Gesamtlänge aller Dateinamen in die Befehlszeile passt, ist das Weiterleiten durch sort -z( --zero-terminated) einfacher als das Herumspielen mit einer Reihe von Dateien.
Anton Samsonov

@AntonSamsonov Dies ist ein wirklich altes Skript, ich habe gerade Skripting gelernt. Ich habe es seitdem ein paar Mal umgeschrieben. In Bezug auf Ihren Kommentar, was die Null-Terminierung beim Sortieren bewirkt: Ich habe die Manpage of sort gelesen. Sie sagen, dass ein Null-Abschluss ein Null-Byte am Ende der Zeile anstelle einer neuen Zeile klebt. Was bringt das?
Thebunnyrules

Ich habe ein Update für dieses Skript als eine separate Antwort hier gepostet: superuser.com/questions/458326/...
thebunnyrules

4

EINFÜHRUNG

Vor einigen Jahren habe ich ein Skript geschrieben und vorgestellt (in diesem Thread), das die Hash-Signaturen aller einzelnen Dateien in der aktuellen Verzeichnisstruktur überprüfen und als Liste in einer Textdatei ausgeben kann.

Seitdem habe ich diese Formel mehrmals verfeinert. Ich habe beschlossen, mein neues und verbessertes Skript hier als separate Antwort neu zu veröffentlichen. Es ist für sha256 geschrieben, aber jeder, der immer noch sha1 verwenden möchte, kann einfach in gedit suchen und ersetzen, um sha256 mit sha1 zu tauschen. Persönlich habe ich sha1 seit ein paar Jahren nicht mehr verwendet und ich würde es nicht empfehlen, da es veraltet ist und Google gezeigt hat, wie es kompromittiert werden kann .

Folgendes macht mein neues Skript:

  1. Sie können das Skript einfach verwenden, indem Sie in das zu hashende Verzeichnis gehen und Folgendes eingeben:

    sha256rec

    Alternativ können Sie dieses Skript auch aus einem anderen Verzeichnis aufrufen:

    sha256rec "/path/to/target/directory/you/want/hash"
  2. Das Skript erkennt, ob Sie über Schreibrechte im aktuellen Verzeichnis verfügen. In diesem Fall werden die Ergebnisse im aktuellen Verzeichnis gespeichert. Wenn Sie keine Schreibrechte haben oder sich Ihr aktuelles Verzeichnis in einem schreibgeschützten System befindet (z. B. eine CD-ROM), werden die Ergebnisse im Basisverzeichnis des aktuellen Benutzers gespeichert.

  3. Das Skript erkennt, ob einige der Unterverzeichnisse mit den aktuellen Benutzerberechtigungen nicht erreichbar sind. Wenn alle lesbar sind, findet keine Erhöhung der Berechtigungen statt. Wenn dies nicht der Fall ist, werden die Berechtigungen des Benutzers auf root erhöht.

  4. Suchen wird verwendet, um alle Dateien in der aktuellen Verzeichnisstruktur (einschließlich aller Unterverzeichnisse) zu finden. Sortieren wird verwendet, um sicherzustellen, dass die Ergebnisse alphabetisch ausgegeben werden. Die resultierende Liste wird sha256sum unterzogen und in eine Textdatei ausgegeben.

  5. Seit dem Schreiben des alten Skripts habe ich eine Designphilosophie angenommen, nach der temporäre Dateien böse sind und nach Möglichkeit vermieden werden sollten, da sie den Benutzern die Möglichkeit geben, von böswilligen Dritten beschnüffelt und manipuliert zu werden. Alle Daten in diesem neuen Skript werden also bis zur letzten Minute als Variablen bearbeitet, wobei die Ergebnisse als Textdatei ausgegeben werden.

  6. Die resultierende Datei selbst wird gehasht und der Pfad / Hash im Terminal ausgegeben. Ich fotografiere diese Hashes gerne mit einer alten Offline-Kamera, um sicherzustellen, dass die Ergebnisdatei nicht manipuliert wird, wenn ich sie zu einem späteren Zeitpunkt wiederhole.

  7. Alte Ergebnisdateien werden bei der Zählung ignoriert. Das erleichtert das Vergleichen der Ergebnisse.

Hier ist ein Beispiel für die Terminalausgabe beim Ausführen meines Skripts:

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$ 

Hier ist ein Ausschnitt der Ausgabe, die in 000_sha256sum_recurs_linux-headers-4.13.0-16-generic_d_22-04-2018_t_02.17.txt zu finden ist:

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

(Es geht weiter für weitere 7000+ Zeilen wie diese, aber Sie bekommen die Idee)

INSTALLATION

  1. Öffnen Sie ein Terminal und geben Sie die folgenden Befehle ein:

    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. Verwenden Sie in Nano zum Einfügen die Tastenkombination Umschalt + Strg + v. Strg-O und Enter zum Speichern. Ctr-X wird beendet. Füge mein Skript dort ein:

(Einfügen nach dem #! / 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. Achten Sie beim Verlassen von nano darauf, den erhöhten Status zu verlassen, indem Sie Folgendes eingeben:

    exit

ABSCHLIESSENDE GEDANKEN

  1. Dies funktioniert nur, wenn Sie Bash installiert haben. Ich habe eine Synthax für die Manipulation von Teilzeichenfolgen verwendet, die mit sh, dash, ksh oder zsh nicht funktioniert. Sie können weiterhin eine der anderen Shells als tägliche Treiber verwenden, aber bash muss installiert sein.

  2. Ausgegebene Listen können mit verschiedenen Tools verglichen werden, z. B .: (im Terminal) diff, sdiff (und grafisch) diffuse, kdiff, winmerge.

  3. Meine Datei sortiert die Ausgabe nach dem Pfad, damit sie von Menschen leichter gelesen werden kann. Ich habe festgestellt, dass der Sortierbefehl in verschiedenen Distributionen unterschiedlich funktioniert. Beispielsweise hatten in einer Distribution GROSSBUCHSTABEN Vorrang vor Großbuchstaben und in der anderen nicht. Dies wirkt sich auf die Zeilenreihenfolge der Ausgabedateien aus und kann den Vergleich von Dateien erschweren. Dies sollte keine Probleme aufwerfen, wenn Sie das Skript immer in derselben Distribution verwenden. Dies kann jedoch der Fall sein, wenn Hash-Listen in zwei verschiedenen Umgebungen generiert wurden. Dies lässt sich leicht beheben, indem Hash-Dateien eine zusätzliche Zeit lang sortiert werden, sodass die Zeilen nach Hash und nicht nach Pfad geordnet werden:

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

Eine robustere shebang Linie wäre #!/usr/bin/env bash- es Bash in anderen Verzeichnissen als auch finden wird, weil diese kann in installiert werden / usr / bin , anstatt / bin zum Beispiel inzwischen env neigt dazu , in sein / usr / bin zu allen Zeiten soweit mir aufgefallen ist. Da Sie Bash benötigen, können Sie auch einen [[ blah-blah ]]bedingten Ausdruck in doppelter Klammer anstelle einer allgemeineren [ blah-blah ]Variante in einfacher Klammer verwenden.
Anton Samsonov

Danke für die Hinweise. Ich habe gerade die Bedingungen nachgeschlagen. Sie sehen wirklich nützlich aus.
Thebunnyrules

Die Sorge, dass SHA1 kompromittiert wird, trifft nicht wirklich zu, wenn Dateien nach dem Kopieren verglichen werden, um die Integrität zu überprüfen. Die Wahrscheinlichkeit, dass eine Datei während der Übertragung beschädigt wird, aber immer noch denselben SHA1 hat, ist praktisch gleich Null. Wenn Sie vermuten, dass ein Angreifer genügend Zeit hatte, um eine andere Datei mit einem kollidierenden SHA1 zu generieren, verwenden Sie SHA256. Für den typischen Fall des Kopierens von Dateien ist dies jedoch übertrieben und langsamer als SHA1 oder MD5 .
Dan Dascalescu

Dein eigenes Argument kann gegen sich selbst verwendet werden. Wenn Sie sich Sorgen über normale (nicht angriffsbedingte) Korruption machen, ist sha1 selbst übertrieben. Mit md5 / crc32 können Sie schnellere Ergebnisse erzielen. In beiden Situationen (Manipulationserkennung oder Beschädigung) ist sha1 nicht geeignet. Persönlich verwende ich diese Hash-Listen für beide Szenarien und habe seit dem Upgrade auf sha256 keine wahrnehmbaren Leistungseinbußen bemerkt, aber ich betreibe auch keinen Megaserver. Wie ich in der Antwort sagte, können Sie jeden gewünschten Hash verwenden, indem Sie meinen Befehl sha256sum durch den gewünschten ersetzen: sha1sum, md5sum, b2sum, crc32 ...
thebunnyrules

1

Das scheint bei mir zu funktionieren:

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

BEARBEITEN: Dadurch werden nur alle im Verzeichnisbaum enthaltenen Dateien zusammengefasst. Wenn der Name eines Verzeichnisses geändert wurde, kann dies nicht erkannt werden. Vielleicht so etwas wie:

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

Würde es tun. Etwa die gleiche Antwort wie die andere


1

Ein weiterer Trick könnte darin bestehen, tar zu verwenden, um die Dateiinhalte und Metadaten zu hashen:

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


1
Das funktioniert nicht. tar enthält einen Zeitstempel für einige Betriebssysteme (wie OSX) und die sha1sum wird bei jedem Lauf anders sein.
Srossross

Was @srossross gesagt hat. Wenn Sie auf den beiden Hosts unterschiedliche Versionen von tar haben, sind die Ausgaben unterschiedlich.
Dan Dascalescu

1

Schnelle, robuste und tragbare Lösung

Im Gegensatz zu einigen anderen Lösungen tarfunktioniert die folgende Lösung auf jedem Computer mit den Standard-Unix-Dienstprogrammen und ist durch Parallelisierung der Prüfsumme schneller als alle anderen Lösungen:

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

Da am Ende eine Sortierung verwendet wird, gibt es keinen Echtzeitfortschritt. Lassen Sie den Befehl einfach ausführen.

Hier ist, was die Argumente tun:

  • find . -type f findet alle Dateien im aktuellen Verzeichnis und seinen Unterverzeichnissen
  • xargs -d'\n'teilt die Ausgabe von find in Zeilen auf (wenn Sie erwarten, dass Dateien mit Zeilenumbrüchen enthalten sind, gehen Sie wie gewohnt vor find -print0 | xargs -0)
  • -P0 n1Läuft md5sumin parallelen Prozessen mit der maximalen Anzahl von Prozessen, die von der Maschine unterstützt werden (Multi-Core!)
  • sort -k 2sortiert nach dem zweiten Feld der md5sumAusgabe, das den vollständigen Pfad zu jeder Datei angibt (das erste ist das MD5)
  • Das Finale md5sumberechnet eine Prüfsumme aus der Liste der Dateiprüfsummen, sodass Sie eine Prüfsumme des gesamten Verzeichnisses in einer Zeile erhalten, die Sie visuell problemlos über Terminalfenster hinweg vergleichen können

Bevor Sie sagen, dass "MD5 kompromittiert wurde", denken Sie daran, was Ihr Bedrohungsmodell ist. Versuchen Sie sicherzustellen, dass die Dateien, die Sie von einem anderen Host oder Datenträger kopiert haben, intakt angekommen sind? Dann ist MD5 mehr als ausreichend, da die Wahrscheinlichkeit, dass eine Datei während der Übertragung beschädigt wird, jedoch dasselbe MD5 aufweist, null ist. Wenn Sie jedoch befürchten, dass ein Angreifer die Zeit hat, eine Datei durch eine andere mit einer kollidierenden Prüfsumme zu ersetzen, verwenden Sie sha256sum. Der Nachteil ist, dass SHA-Funktionen langsamer sind als MD5 .

Ausführlicher Fortschritt in Echtzeit

Wenn Sie den Fortschritt in Echtzeit sehen möchten, ändern Sie die Pipeline, um eine temporäre Datei für die Prüfsummen zu verwenden:

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

(Beachten Sie, dass das Verschieben sortnach rechts findnicht funktioniert, da xargs -P0parallelisiert md5sumwird und die Ergebnisse möglicherweise nicht in der richtigen Reihenfolge angezeigt werden.)

Diese Version des Befehls können Sie auch diff die beiden /tmp/sumsDateien (stellen Sie sicher , dass die zweite umbenennen , wenn sie auf der gleichen Maschine ist) und sehen , welche Dateien unterscheiden.


0

Anstatt EINE riesige Datei mit allen gehashten Informationen zu haben, suchte ich nach einer Möglichkeit, eine Datei in jedem Ordner eines Baums zu erstellen. Ich habe mich von den Kommentaren hier inspirieren lassen. Meins ist etwas komplexer als das, was hier gepostet wird. Ich verwende die Dateirotation, aber dies ist für neue Player die am wenigsten komplexe. In dieser Version werden die alten Prüfsummen durch neue überschrieben. Es kann sinnvoll sein, 2-3 Versionen beizubehalten, je nachdem, wie häufig Sie es ausführen und wie tief Sie es benötigen.

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

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

Beachten Sie, dass mkshaindir für meine Zwecke eine separate Komponente ist, da ich möglicherweise einen Hash für Dateien in einem neuen Ordner oder einen kürzlich geänderten Ordner erstellen muss. Dies alles kann bei Bedarf in einem Skript kombiniert werden.

Der Rest bleibt als Übung für den Leser.


0

basierend auf der vorherigen Antwort :

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

  • stabile Sorte
  • numerische Besitzer- und Gruppen-ID
  • wortreicher Fortschritt
  • Dateiname sicher

Dies funktionierte nicht in einem kopierten Verzeichnis, das nur eine Datei enthielt, und ich vermute, dass dies daran lag, dass ich auf dem Remote-Host eine etwas ältere Version von tar (1.28) im Vergleich zu 1.29 auf dem lokalen Host ausführte. Leider Teer 1.29 wird nicht zurückportiert auf Xenial.
Dan Dascalescu

0

@allquixoticDie Antwort von generiert nicht dieselben Hashes auf verschiedenen Computern, die uns nicht dabei helfen, zu überprüfen und konsistente Hashes zu haben.

Die folgende Zeile find . -type f \( -exec md5sum "$PWD"/{} \; \)gibt die folgende Ausgabe zurück:

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

Daher wäre der Pfad auf verschiedenen Maschinen unterschiedlich. awk '{print $1}'wird uns helfen, die erste Spalte zu erhalten, die nur den Hash der Dateien enthält. Später müssen wir diese Hashes sortieren, wobei die Reihenfolge auf verschiedenen Computern unterschiedlich sein kann. Dies kann auch dazu führen, dass wir unterschiedliche Hashes haben, wenn mehr als zwei Dateien vorhanden sind.


Lösung:

Für Mac:

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

Für Linux:

find ./path/to/directory/ -type f \( -exec md5sum "$PWD"/{} \; \) | awk '{print $1}' | sort | md5sum | awk '{print $1}'
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.