sha1sum per una directory di directory


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

quanto sopra è stato pubblicato come un modo per calcolare uno sha1sum di una directory che contiene file. Questo comando ha esito negativo se la directory include più directory. C'è un modo per calcolare ricorsivamente lo sha1sum di una directory di directory universalmente (senza adattamento personalizzato di un algoritmo alla directory specifica in questione)?

Risposte:


14

Grazie a questo post SO -

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

Attenzione: questo codice non è testato ! Modifica questa domanda se è sbagliata e puoi risolverla; Approverò la tua modifica.


Scusate; Non ho resistito! ;-) La ricorsione è divertente. Certo che c'è un modo. Scriverò una risposta adeguata ora.
allquixotic,

3
Questo non genererà lo stesso hash per le stesse identiche cartelle su macchine diverse poiché l'output contiene anche <hash> e <percorso file> il cui percorso file è diverso su macchine diverse e causa hash diversi su macchine diverse. Linea corretta dovrebbe essere come find . -type f \( -exec sha1sum "$PWD"/{} \; \) | awk '{print $1}' | sort | sha1sum@allquixotic
Alper

1
Inoltre, gli hash dei file devono essere ordinati, il che causerà anche hash diversi se l'ordinamento è diverso su macchine diverse.
alper

40

In genere mi piace il modello "trova | xargs", in questo modo:

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

Devi usare "-print0" e "-0", nel caso ci siano spazi nei nomi dei file.

Tuttavia, questo è molto simile al modello "trova -exec cmd {}".

Guarda una discussione confrontando i due modelli qui: /programming/896808/find-exec-cmd-vs-xargs


La tua risposta restituisce solo l'hash dei file. L'hash della cartella dovrebbe essere ottenuto usando find . -type f -print0 | xargs -0 sha1sum | awk '{print $1}' | sha1sum.
alper

5

AGGIORNAMENTO: Sono passati alcuni anni da quando ho pubblicato questa risposta e nel frattempo ho riscritto e migliorato la sceneggiatura che ho presentato qui diverse volte. Ho deciso di ripubblicare la nuova sceneggiatura come una nuova risposta. Lo consiglio vivamente su questo.

INTRODUZIONE

Ho osservato che l'ordine in cui il comando find genera gli elementi trovati all'interno di una directory varia all'interno di directory identiche su partizioni diverse. Se stai confrontando gli hash della stessa directory, non devi preoccuparti di questo, ma se stai ottenendo gli hash per assicurarti che nessun file sia stato perso o danneggiato durante una copia, devi includere una riga aggiuntiva per ordinamento del contenuto della directory e dei suoi elementi. Ad esempio, la risposta di Matthew Bohnsack è piuttosto elegante:

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

Ma se lo stai usando per confrontare una directory copiata con la sua originale, invierai l'output in un file txt che confronteresti con la lista in uscita dall'altra directory usando Kompare o WinMerge o semplicemente ottenendo gli hash di ogni lis . Il fatto è che, poiché l'ordine in cui lo strumento di ricerca produrrà il contenuto può variare da una directory all'altra, Kompare segnalerà molte differenze perché gli hash non sono stati calcolati nello stesso ordine. Non è un grosso problema per le piccole directory ma piuttosto fastidioso se hai a che fare con 30000 file. Pertanto, è necessario eseguire i passaggi aggiuntivi per ordinare l'output per semplificare il confronto degli elenchi di hash tra le due directory.

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

Ciò ordinerebbe l'output in modo che i file con lo stesso hash si trovino sulle stesse righe quando si esegue il programma di differenziazione (a condizione che non manchi alcun file nella nuova directory).

E SULLA SCRITTURA ...

Ecco una sceneggiatura che ho scritto. Fa la stessa cosa che fa la risposta find / xarg ma ordina i file prima di ottenere sha1sum (mantenendoli nella stessa directory). La prima riga dello script trova ricorsivamente tutti i file all'interno della directory. Il prossimo ordina i risultati in ordine alfabetico. I due seguenti, prendono il contenuto ordinato e aggiungono uno sha1sum e virgolette ai file nell'elenco ordinato, creando uno script di grandi shell che calcola ogni hash di file, uno alla volta e lo invia a 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

Spero che sia di aiuto.


Quando la lunghezza totale di tutti i nomi di file rientra nella riga di comando, il piping attraverso sort -z( --zero-terminated) è più facile che fare confusione con un mucchio di file.
Anton Samsonov,

@AntonSamsonov Questa è una sceneggiatura molto vecchia, stavo solo imparando la sceneggiatura in quel momento. Da allora l'ho riscritto un sacco di volte. Per quanto riguarda il tuo commento cosa fa la terminazione zero durante l'ordinamento: ho letto la pagina man dell'ordinamento. Dicono che la terminazione zero attacca un byte zero alla fine della riga anziché una nuova riga. Cosa compie questo?
thebunnyrules il

Ho pubblicato un aggiornamento a questo script come risposta separata qui: superuser.com/questions/458326/…
thebunnyrules

4

INTRODUZIONE

Qualche anno fa, ho scritto e presentato (proprio in questo thread) uno script che può controllare le firme hash di tutti i singoli file nella struttura di directory corrente e inviarlo come elenco in un file di testo.

Da allora, ho perfezionato questa formula più volte. Ho deciso di ripubblicare qui il mio script nuovo e migliorato come risposta separata. È scritto per sha256 ma chiunque voglia ancora usare sha1 può fare una semplice ricerca e sostituire in gedit per scambiare sha256 con sha1. Personalmente, non uso sha1 da un paio d'anni e non lo consiglierei perché è diventato antiquato e google ha dimostrato come può essere compromesso .

Ecco cosa fa il mio nuovo script:

  1. Puoi semplicemente usare lo script andando nella directory che vuoi hash e inserendo:

    sha256rec

    In alternativa, puoi chiamare questo script da un'altra directory facendo:

    sha256rec "/path/to/target/directory/you/want/hash"
  2. Lo script rileverà se hai i privilegi di scrittura nella directory corrente. In tal caso, i risultati verranno salvati nella directory corrente. Se non si dispone dei privilegi di scrittura o se la directory corrente si trova in un sistema di sola lettura (come un cdrom), i risultati verranno salvati nella home directory dell'utente corrente.

  3. Lo script rileverà se alcune delle sottodirectory non sono accessibili ai privilegi dell'utente corrente. Se tutti sono leggibili, allora non ha luogo alcun aumento dei privilegi, se non lo sono, i privilegi dell'utente vengono elevati alla radice.

  4. Trova viene utilizzato per trovare tutti i file nella struttura dir corrente (incluse tutte le sottodirectory). L'ordinamento viene utilizzato per assicurarsi che i risultati vengano emessi in ordine alfabetico. L'elenco risultante viene sottoposto a sha256sum e viene emesso in un file di testo.

  5. Da quando ho scritto la vecchia sceneggiatura ho adottato una filosofia di progettazione secondo cui i file temporanei sono dannosi e dovrebbero essere evitati quando possibile poiché lasciano gli utenti aperti a ficcanaso e manomissione da parte di terzi malintenzionati. Quindi tutti i dati in questo nuovo script vengono manipolati come variabili fino all'ultimo minuto in cui i risultati vengono emessi come file di testo.

  6. Lo stesso file risultante viene sottoposto a hash e il percorso / hash viene emesso nel terminale. Mi piace scattare foto di questi hash con una fotocamera offline della vecchia scuola per essere in grado di garantire che il file dei risultati non sia stato manomesso quando mi riferisco ad esso in un secondo momento.

  7. I vecchi file dei risultati vengono ignorati nel conteggio. Semplifica il confronto dei risultati.

Ecco un esempio dell'output del terminale quando eseguo il mio script:

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$ 

Ecco uno snippet dell'output che può essere trovato in 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

(continua per altre 7000+ righe come questa ma hai l'idea)

INSTALLAZIONE

  1. Apri un terminale e inserisci i seguenti comandi:

    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. In nano, usa Shif + Ctrl + v per incollare. Ctrl-O e Invio per salvare. Ctr-X esce. Incolla qui la mia sceneggiatura:

(incolla dopo #! / 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. Quando esci da nano, assicurati di uscire dallo stato elevato inserendo:

    exit

PENSIERI FINALI

  1. Funzionerà solo se hai installato bash. Ho usato un po 'di sintassi per manipolare la sottostringa che non funziona con sh, dash, ksh o zsh. Puoi comunque usare qualsiasi altra shell come driver quotidiano ma bash deve essere installato.

  2. Le liste di output possono essere confrontate con una varietà di strumenti come: (nel terminale) diff, sdiff (e grafico) diffuso, kdiff, winmerge.

  3. Il mio file ordina l'output in base al percorso, per facilitarne la lettura da parte degli umani. Ho notato che il comando di ordinamento funziona in modo diverso su diverse distro. Ad esempio, in una distro le lettere in MAIUSC hanno avuto la priorità sulle non maiuscole e nell'altra no. Ciò influisce sull'ordine delle righe dei file di output e potrebbe rendere difficile il confronto dei file. Ciò non dovrebbe presentare alcun problema se si utilizza sempre lo script nella stessa distro, ma può verificarsi se gli elenchi di hash sono stati generati in due ambienti diversi. Questo è facilmente risolto ordinando i file hash un'ulteriore volta in modo che le linee vengano ordinate in base all'hash anziché al percorso:

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

Una linea shebang più robusta sarebbe #!/usr/bin/env bash- troverà Bash in altre directory come bene, perché quest'ultimo può essere installato in / usr / bin invece che / bin , ad esempio, nel frattempo ENV tende ad essere in / usr / bin in ogni momento per quanto ho notato. Vale anche la pena notare che, poiché è necessario Bash, è possibile utilizzare [[ blah-blah ]]un'espressione condizionale tra parentesi doppie anziché una [ blah-blah ]variante più generica con parentesi singola.
Anton Samsonov,

Grazie per i suggerimenti. Ho appena finito di cercare i [[condizionali. Sembrano davvero utili.
thebunnyrules il

La preoccupazione per la compromissione di SHA1 non è realmente applicabile nel caso di confronto di file dopo la copia per verificarne l'integrità. Le possibilità che un file venga danneggiato durante il trasporto ma che abbiano lo stesso SHA1 sono praticamente nulle. Se sospetti che un utente malintenzionato abbia avuto abbastanza tempo per generare un file diverso con un SHA1 in collisione, utilizza SHA256, ma nel caso tipico della copia di file, è eccessivo e più lento di SHA1 o MD5 .
Dan Dascalescu il

Il tuo argomento può essere usato contro se stesso. Se sei preoccupato per la normale corruzione (non legata agli attacchi), allora sha1 stesso è eccessivo. Puoi ottenere risultati più veloci usando md5 / crc32. In entrambe le situazioni (rilevazione manomissione o corruzione) sha1 non è adatto. Personalmente, utilizzo questi elenchi di hash per entrambi gli scenari e non ho notato alcun impatto sulle prestazioni percepibile da quando ho eseguito l'aggiornamento a sha256 ma non eseguo nemmeno un mega server. Come ho detto nella risposta, sei libero di usare qualsiasi hash che desideri sostituendo il mio comando sha256sum con quello che vuoi: sha1sum, md5sum, b2sum, crc32 ...
thebunnyrules

1

Questo sembra funzionare per me:

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

EDIT: questo solo sha1sum tutti i file contenuti nella struttura di directory. Se il nome di una directory fosse cambiato, questo non lo prenderebbe. Forse qualcosa del tipo:

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

Lo farebbe. Circa la stessa risposta dell'altra però


1

Un altro trucco potrebbe essere usare tar per eseguire l'hash del contenuto e dei metadati del file:

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


1
Questo non funziona. tar include un timestamp per alcuni sistemi operativi (come OSX) e sha1sum sarà diverso a ogni esecuzione.
srossross,

Cosa ha detto @srossross. Inoltre, se hai due versioni diverse di tar sui due host, le uscite saranno diverse.
Dan Dascalescu,

1

Soluzione veloce, robusta e portatile

A differenza di alcune delle altre soluzioni che coinvolgono tar, la soluzione seguente funziona su qualsiasi macchina che abbia le utility Unix standard ed è più veloce di tutte le altre soluzioni parallelizzando il checksum:

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

Dal momento che usa un ordinamento alla fine, non ci sono progressi in tempo reale, quindi basta eseguire il comando.

Ecco cosa fanno gli argomenti:

  • find . -type f trova tutti i file nella directory corrente e nelle sue sottodirectory
  • xargs -d'\n'suddivide l'output di find in righe (se si prevede di avere file con newline in essi, quindi fare il solito find -print0 | xargs -0)
  • -P0 n1funziona md5sumin processi paralleli, utilizzando il numero massimo di processi supportati dalla macchina (multi-core!)
  • sort -k 2ordina per il secondo campo md5sumdell'output, che è il percorso completo di ciascun file (il primo è l'MD5)
  • il finale md5sumcalcola un checksum dell'elenco dei checksum dei file, in modo da ottenere un checksum dell'intera directory su una riga, che puoi facilmente confrontare visivamente tra le finestre del terminale

Prima di dire che "MD5 è stato compromesso", tieni presente qual è il tuo modello di minaccia. Stai cercando di assicurarti che i file che hai copiato da qualche altro host o disco siano arrivati ​​intatti? Quindi MD5 è più che sufficiente, perché le possibilità che un file venga danneggiato durante il trasporto ma con lo stesso MD5 sono zero. Ma se hai paura che un utente malintenzionato abbia il tempo di sostituire un file con un altro con un checksum in conflitto, usa sha256sum. Il rovescio della medaglia è che le funzioni SHA sono più lente di MD5 .

Progressi dettagliati in tempo reale

Infine, se vuoi vedere i progressi in tempo reale, modifica la pipeline per usare un file temporaneo per i checksum:

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

(Nota che spostare il sorttasto destro dopo findnon funzionerebbe, perché si xargs -P0parallelizza md5sume i risultati possono arrivare fuori servizio.)

Questa versione del comando ti consente anche di differenziare i due /tmp/sumsfile (assicurati di rinominare il secondo se si trova sulla stessa macchina) e vedere quali file differiscono.


0

Piuttosto che avere UN enorme file contenente tutte le informazioni con hash che cercavo un modo per creare un file in ogni cartella di un albero. Ho preso ispirazione dai commenti qui. Il mio è un po 'più complesso di quanto pubblicato qui. Uso la rotazione dei file ma questa è la meno complessa per i nuovi giocatori. Questa versione lo farà sovrascrivere le somme di controllo vecchie con quelle nuove. Potrebbe essere utile mantenere 2-3 versioni a seconda della frequenza con cui lo si esegue e del bisogno di "profondità".

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

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

Nota che mkshaindir, per i miei scopi, è un componente separato perché potrebbe essere necessario per me creare un hash di file in una nuova cartella o di uno che è stato modificato di recente. Tutto questo può essere combinato in uno script, se necessario.

Il resto è lasciato come esercizio per il lettore.


0

basato sulla risposta precedente :

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

  • ordinamento stabile
  • proprietario numerico e ID gruppo
  • progresso dettagliato
  • nome file sicuro

Questo non ha funzionato su una directory copiata contenente solo un file, e sospetto che fosse perché stavo eseguendo una versione leggermente più vecchia di tar (1.28) sull'host remoto, rispetto a 1.29 sull'host locale. Sfortunatamente, tar 1.29 non è stato backportato su Xenial.
Dan Dascalescu il

0

@allquixoticLa risposta non genera gli stessi hash su macchine diverse che non ci aiuteranno a verificare e avere hash coerenti.

La riga find . -type f \( -exec md5sum "$PWD"/{} \; \)seguente restituisce il seguente output:

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

Quindi il percorso sarebbe diverso su macchine diverse. awk '{print $1}'ci aiuterà a ottenere la prima colonna, che ha solo l'hash dei file. Successivamente dobbiamo ordinare quegli hash, in cui l'ordine potrebbe essere diverso su macchine diverse, il che potrebbe anche farci avere hash diversi se ci sono più di due file.


Soluzione:

Per Mac:

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

Per Linux:

find ./path/to/directory/ -type f \( -exec md5sum "$PWD"/{} \; \) | awk '{print $1}' | sort | md5sum | awk '{print $1}'
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.