Il modo giusto dipende esattamente dal motivo per cui stai chiedendo:
Opzione 1: confronta solo i dati
Se hai solo bisogno di un hash del contenuto del file dell'albero, questo funzionerà:
$ find -s somedir -type f -exec md5sum {} \; | md5sum
Questo prima riassume tutti i contenuti dei file singolarmente, in un ordine prevedibile, quindi passa quell'elenco di nomi di file e hash MD5 da eseguire l'hash stesso, dando un singolo valore che cambia solo quando cambia il contenuto di uno dei file nella struttura.
Sfortunatamente, find -s
funziona solo con BSD find (1), utilizzato in macOS, FreeBSD, NetBSD e OpenBSD. Per ottenere qualcosa di paragonabile su un sistema con GNU o SUS find (1), hai bisogno di qualcosa di un po 'più brutto:
$ find somedir -type f -exec md5sum {} \; | sort -k 2 | md5sum
Abbiamo sostituito find -s
con una chiamata a sort
. Il -k 2
bit gli dice di saltare l'hash MD5, quindi ordina solo i nomi dei file, che sono nel campo 2 fino alla fine della riga, secondo sort
i calcoli.
C'è una debolezza con questa versione del comando, che è che potrebbe confondersi se ci sono nomi di file con nuove righe, perché sembreranno più righe alla sort
chiamata. La find -s
variante non ha questo problema, perché l'attraversamento e l'ordinamento degli alberi avvengono all'interno dello stesso programma find
,.
In entrambi i casi, l'ordinamento è necessario per evitare falsi positivi: i filesystem Unix / Linux più comuni non mantengono gli elenchi di directory in un ordine stabile e prevedibile. Potresti non rendertene conto dall'uso ls
e simili, che ordinano silenziosamente il contenuto della directory per te. find
senza -s
o una sort
chiamata stamperà i file nell'ordine in cui li restituiscono i filesystem sottostanti, il che farà sì che questo comando dia un valore hash modificato se l'ordine dei file che gli vengono dati come input cambia.
Potrebbe essere necessario modificare i md5sum
comandi md5
o un'altra funzione hash. Se si sceglie un'altra funzione hash e si necessita della seconda forma del comando per il proprio sistema, potrebbe essere necessario modificare il sort
comando di conseguenza. Un'altra trappola è che alcuni programmi di somma dei dati non scrivono affatto un nome di file, ad esempio il vecchio sum
programma Unix .
Questo metodo è in qualche modo inefficiente, chiamando md5sum
N + 1 volte, dove N è il numero di file nella struttura, ma è un costo necessario per evitare hash e metadati della directory.
Opzione 2: confronta dati e metadati
Se devi essere in grado di rilevare che qualcosa è cambiato in un albero, non solo il contenuto del file, chiedi tar
di impacchettare il contenuto della directory per te, quindi invialo a md5sum
:
$ tar -cf - somedir | md5sum
Poiché tar
vede anche le autorizzazioni dei file, la proprietà, ecc., Questo rileverà anche le modifiche a tali elementi, non solo le modifiche al contenuto del file.
Questo metodo è considerevolmente più veloce, poiché effettua solo un passaggio sull'albero ed esegue il programma hash solo una volta.
Come per il find
metodo basato sopra, tar
elabora i nomi dei file nell'ordine in cui li restituisce il file system sottostante. Potrebbe essere che nella tua applicazione, puoi essere sicuro di non far sì che ciò accada. Posso pensare ad almeno tre diversi schemi di utilizzo in cui è probabile che ciò avvenga. (Non li elencherò, perché stiamo entrando in un territorio di comportamento non specificato. Ogni file system può essere diverso qui, anche da una versione del sistema operativo alla successiva.)
Se ti accorgi che stai ottenendo falsi positivi, ti consiglio di find | cpio
scegliere l' opzione nella risposta di Gilles .
find .
posto difind somedir
. In questo modo i nomi dei file sono gli stessi quando si forniscono specifiche di percorso diverse da trovare; questo può essere difficile :-)