GNU/Linux >> Linux Esercitazione >  >> Linux

Come posso calcolare un checksum md5 di una directory?

Crea al volo un file di archivio tar e reindirizzalo a md5sum :

tar c dir | md5sum

Ciò produce un singolo valore hash MD5 che dovrebbe essere univoco per la configurazione del file e della sottodirectory. Nessun file viene creato su disco.


Se ti interessano solo i file e non le directory vuote, funziona bene:

find /path -type f | sort -u | xargs cat | md5sum

il suggerimento di ire_and_curses di usare tar c <dir> presenta alcuni problemi:

  • tar elabora le voci di directory nell'ordine in cui sono memorizzate nel filesystem e non c'è modo di cambiare quest'ordine. Questo effettivamente può produrre risultati completamente diversi se hai la "stessa" directory in posti diversi, e non conosco alcun modo per risolvere questo problema (tar non può "ordinare" i suoi file di input in un ordine particolare).
  • Di solito mi interessa sapere se i numeri groupid e ownerid sono gli stessi, non necessariamente se la rappresentazione in stringa di group/owner è la stessa. Questo è in linea con ciò che per esempio rsync -a --delete fa:sincronizza praticamente tutto (meno xattrs e acls), ma sincronizzerà proprietario e gruppo in base al loro ID, non sulla rappresentazione di stringa. Quindi, se hai eseguito la sincronizzazione con un sistema diverso che non ha necessariamente gli stessi utenti/gruppi, dovresti aggiungere --numeric-owner flag per tar
  • tar includerà il nome del file della directory che stai controllando, solo qualcosa di cui essere a conoscenza.

Finché non esiste una soluzione per il primo problema (o a meno che tu non sia sicuro che non ti riguardi), non utilizzerei questo approccio.

Il find proposto anche le soluzioni basate su - non vanno bene perché includono solo file, non directory, il che diventa un problema se il checksum deve tenere a mente le directory vuote.

Infine, la maggior parte delle soluzioni suggerite non ordina in modo coerente, perché le regole di confronto potrebbero essere diverse tra i sistemi.

Questa è la soluzione che ho trovato:

dir=<mydir>; (find "$dir" -type f -exec md5sum {} +; find "$dir" -type d) | LC_ALL=C sort | md5sum

Note su questa soluzione:

  • Il LC_ALL=C è garantire un ordinamento affidabile tra i sistemi
  • Questo non fa differenza tra una directory "named\nwithanewline" e due directory "named" e "withanewline", ma la possibilità che ciò accada sembra molto improbabile. Uno di solito risolve questo problema con un -print0 flag per find , ma dal momento che ci sono altre cose da fare qui, posso solo vedere soluzioni che renderebbero il comando più complicato di quanto valga.

PS:uno dei miei sistemi utilizza un busybox limitato find che non supporta -exec-print0 flags, e inoltre aggiunge '/' per indicare le directory, mentre findutils find non sembra, quindi per questa macchina devo eseguire:

dir=<mydir>; (find "$dir" -type f | while read f; do md5sum "$f"; done; find "$dir" -type d | sed 's#/$##') | LC_ALL=C sort | md5sum

Fortunatamente, non ho file/directory con newline nei loro nomi, quindi questo non è un problema su quel sistema.


find /path/to/dir/ -type f -name "*.py" -exec md5sum {} + | awk '{print $1}' | sort | md5sum

La trova Il comando elenca tutti i file che terminano con .py. Il valore hash MD5 viene calcolato per ogni file .py. AWK viene utilizzato per selezionare i valori hash MD5 (ignorando i nomi dei file, che potrebbero non essere univoci). I valori hash MD5 vengono ordinati. Viene quindi restituito il valore hash MD5 di questo elenco ordinato.

L'ho testato copiando una directory di test:

rsync -a ~/pybin/ ~/pybin2/

Ho rinominato alcuni file in ~/pybin2 .

Il find...md5sum Il comando restituisce lo stesso output per entrambe le directory.

2bcf49a4d19ef9abd284311108d626f1  -

Per tenere conto del layout del file (percorsi), quindi il checksum cambia se un file viene rinominato o spostato, il comando può essere semplificato:

find /path/to/dir/ -type f -name "*.py" -exec md5sum {} + | md5sum

Su macOS con md5 :

find /path/to/dir/ -type f -name "*.py" -exec md5 {} + | md5

Linux
  1. Shell - Come trovare la directory di alcuni comandi?

  2. Come posso creare un file in ogni cartella?

  3. Come posso eseguire dos2unix su un'intera directory?

  4. Come contare il numero di file in ogni directory?

  5. Come posso trovare un file/directory che potrebbe trovarsi ovunque sulla riga di comando di Linux?

Come contare i file nella directory in Linux

Come trovare la dimensione totale di una directory in Linux

Come posso trovare il file più vecchio in un albero di directory

Come posso rimuovere un file o una directory chiamata \?

Come posso trovare le interfacce di rete disponibili?

Non riesci a trovare .so nella stessa directory dell'eseguibile?