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 -sfunziona 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 -scon una chiamata a sort. Il -k 2bit 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 sorti 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 sortchiamata. La find -svariante 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 lse simili, che ordinano silenziosamente il contenuto della directory per te. findsenza -so una sortchiamata 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 md5sumcomandi md5o 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 sortcomando di conseguenza. Un'altra trappola è che alcuni programmi di somma dei dati non scrivono affatto un nome di file, ad esempio il vecchio sumprogramma Unix .
Questo metodo è in qualche modo inefficiente, chiamando md5sumN + 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 tardi impacchettare il contenuto della directory per te, quindi invialo a md5sum:
$ tar -cf - somedir | md5sum
Poiché tarvede 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 findmetodo basato sopra, tarelabora 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 | cpioscegliere 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 :-)