GNU/Linux >> Linux Esercitazione >  >> Linux

Come ottenere la somma Md5 dei contenuti di una directory come una somma?

Il programma md5sum non fornisce checksum per le directory. Voglio ottenere un singolo checksum MD5 per l'intero contenuto di una directory, inclusi i file nelle sottodirectory. Cioè, un checksum combinato composto da tutti i file. C'è un modo per farlo?

Risposta accettata:

Il modo giusto dipende esattamente dal motivo per cui lo stai chiedendo:

Opzione 1:confronta solo i dati

Se hai solo bisogno di un hash del contenuto del file dell'albero, questo farà il trucco:

$ find -s somedir -type f -exec md5sum {} ; | md5sum

Questo prima riassume tutti i contenuti del file individualmente, in un ordine prevedibile, quindi passa quell'elenco di nomi di file e hash MD5 da sottoporre a hash, fornendo un unico valore che cambia solo quando cambia il contenuto di uno dei file nell'albero.

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 imitato il comportamento di BSD find -s aggiungendo 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 per sort sta facendo i conti.

C'è un punto debole in questa versione del comando, che è che può confondersi se hai nomi di file con nuove righe, perché sembreranno più righe per sort chiamata. Il find -s variant non ha questo problema, perché l'attraversamento e l'ordinamento dell'albero avvengono all'interno dello stesso programma, find .

In entrambi i casi, l'ordinamento è necessario per evitare falsi positivi:i più comuni filesystem Unix/Linux non mantengono gli elenchi delle directory in un ordine stabile e prevedibile. Potresti non rendertene conto usando ls e simili, che ordinano silenziosamente il contenuto della directory per te. Chiamando find senza ordinare il suo output in qualche modo farà sì che l'ordine delle righe nell'output corrisponda all'ordine che il filesystem sottostante le restituisce, il che farà sì che questo comando dia un valore hash modificato se l'ordine dei file assegnatogli come input cambia, anche se i dati rimangono identici.

Potresti chiedere se il -k 2 bit in GNU sort il comando sopra è necessario. Dato che l'hash dei dati del file è un proxy adeguato per il nome del file purché il contenuto non sia cambiato, non otterremo falsi positivi se eliminiamo questa opzione, consentendoci di utilizzare lo stesso comando sia con GNU che BSD sort . Tuttavia, renditi conto che c'è una piccola possibilità (1:2 con MD5) che l'ordine esatto dei nomi dei file non corrisponda all'ordine parziale che fa senza -k 2 può dare se c'è mai una collisione di hash. Tieni presente, tuttavia, che se tali piccole possibilità di mancata corrispondenza sono importanti per la tua applicazione, l'intero approccio è probabilmente fuori questione per te.

Correlati:in un ambiente vuoto, come vengono trovati gli eseguibili?

Potrebbe essere necessario modificare il md5sum comandi a md5 o qualche altra funzione hash. Se scegli un'altra funzione hash e hai bisogno della seconda forma del comando per il tuo sistema, potresti dover modificare il sort comandare di conseguenza. Un'altra trappola è che alcuni programmi di somma dei dati non scrivono affatto un nome di file, un ottimo esempio è il vecchio sum di Unix programma.

Questo metodo è alquanto inefficiente, chiamando md5sum N+1 volte, dove N è il numero di file nell'albero, ma è un costo necessario per evitare l'hashing dei metadati di file e directory.

Opzione 2:confronta i dati e Metadati

Se devi essere in grado di rilevare qualsiasi cosa in un albero è cambiato, non solo il contenuto del file, chiedi a tar per imballare il contenuto della directory per te, quindi inviarlo a md5sum :

$ tar -cf - somedir | md5sum

Perché tar vede anche i permessi dei file, la proprietà, ecc., questo rileverà anche le modifiche a queste cose, non solo le modifiche ai contenuti dei file.

Questo metodo è considerevolmente più veloce, poiché effettua un solo passaggio sull'albero ed esegue il programma hash solo una volta.

Come con il find metodo basato sopra, tar elaborerà i nomi dei file nell'ordine in cui il filesystem sottostante li restituisce. Potrebbe anche essere che nella tua applicazione, puoi essere sicuro che non accadrà. Posso pensare ad almeno tre diversi modelli di utilizzo in cui è probabile che sia il caso. (Non li elencherò, perché stiamo entrando in un territorio di comportamento non specificato. Ogni filesystem può essere diverso qui, anche da una versione del sistema operativo a quella successiva.)

Se ti ritrovi a ricevere falsi positivi, ti consiglio di utilizzare il find | cpio opzione nella risposta di Gilles.


Linux
  1. Come trovare il tipo di un file Img e montarlo?

  2. come trovare il proprietario di un file o di una directory in python

  3. Come ottenere la dimensione di tar.gz nel file (MB) in python

  4. Come ottengo la directory assoluta di un file in bash?

  5. Come ottenere solo il numero di righe di un file

Come ottenere la data e l'ora correnti in Python

Come visualizzare il contenuto di un archivio o di un file compresso in Linux

Come ottenere il nome del file dal percorso completo in Linux

Come trovo la posizione MySQL my.cnf

Come trovare il file manager predefinito?

Come combinare il comando 'tar' con 'find'