Il suggerimento di ire_and_curses di utilizzare tar c <dir>
ha alcuni problemi:
- tar elabora le voci della directory nell'ordine in cui sono archiviate nel filesystem e non c'è modo di cambiare questo ordine. Questo può effettivamente produrre risultati completamente diversi se si dispone della "stessa" directory in luoghi 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 importa se i numeri di groupid e ownerid sono uguali, non necessariamente se la rappresentazione di stringhe di gruppo / proprietario è la stessa. Ciò è in linea con ciò che ad esempio
rsync -a --delete
fa: sincronizza praticamente tutto (meno xattrs e acls), ma sincronizzerà il proprietario e il gruppo in base al loro ID, non alla rappresentazione della stringa. Quindi, se ti sei sincronizzato con un sistema diverso che non ha necessariamente gli stessi utenti / gruppi, dovresti aggiungere il --numeric-owner
flag a tar
- tar includerà il nome file della directory che stai controllando, solo qualcosa di cui devi essere consapevole.
Fintanto che non esiste una soluzione per il primo problema (o a meno che tu non sia sicuro che non ti influenzi), non utilizzerei questo approccio.
Le find
soluzioni di base proposte sopra non sono utili perché includono solo file, non directory, 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 mi è venuta in mente:
dir=<mydir>; (find "$dir" -type f -exec md5sum {} +; find "$dir" -type d) | LC_ALL=C sort | md5sum
Note su questa soluzione:
- L'
LC_ALL=C
obiettivo è garantire un ordinamento affidabile tra i sistemi
- Ciò non distingue tra una directory "nominata \ nwithanewline" e due directory "nominate" e "withanewline", ma la probabilità che ciò si verifichi sembra molto improbabile. Uno di solito risolve questo problema con una
-print0
bandiera, find
ma poiché ci sono altre cose in corso qui, posso solo vedere soluzioni che renderebbero il comando più complicato di quanto valga la pena.
PS: uno dei miei sistemi usa una scatola occupata limitata find
che non supporta -exec
né -print0
flag, 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 le nuove righe nei loro nomi, quindi questo non è un problema su quel sistema.