La sugerencia de uso de ire_and_curses tar c <dir>
tiene algunos problemas:
- tar procesa las entradas de directorio en el orden en que se almacenan en el sistema de archivos, y no hay forma de cambiar este orden. Esto efectivamente puede producir resultados completamente diferentes si tiene el "mismo" directorio en diferentes lugares, y no sé cómo solucionarlo (tar no puede "ordenar" sus archivos de entrada en un orden particular).
- Por lo general, me importa si los números groupid y ownerid son iguales, no necesariamente si la representación de cadena de group / owner es la misma. Esto está en línea con lo que hace por ejemplo
rsync -a --delete
: sincroniza prácticamente todo (menos xattrs y acls), pero sincronizará el propietario y el grupo en función de su ID, no en la representación de cadena. Entonces, si se sincronizó con un sistema diferente que no necesariamente tiene los mismos usuarios / grupos, debe agregar el --numeric-owner
indicador a tar
- tar incluirá el nombre de archivo del directorio que está comprobando, solo algo a tener en cuenta.
Mientras no haya una solución para el primer problema (o a menos que esté seguro de que no le afecta), no usaría este enfoque.
Las find
soluciones basadas propuestas anteriormente tampoco son buenas porque solo incluyen archivos, no directorios, lo que se convierte en un problema si la suma de comprobación debe tener en cuenta los directorios vacíos.
Finalmente, la mayoría de las soluciones sugeridas no se clasifican de manera consistente, porque la intercalación puede ser diferente entre los sistemas.
Esta es la solución que se me ocurrió:
dir=<mydir>; (find "$dir" -type f -exec md5sum {} +; find "$dir" -type d) | LC_ALL=C sort | md5sum
Notas sobre esta solución:
- El
LC_ALL=C
objetivo es garantizar un orden de clasificación confiable en todos los sistemas.
- Esto no diferencia entre un directorio "llamado \ nwithanewline" y dos directorios "named" y "withanewline", pero la posibilidad de que eso ocurra parece muy poco probable. Por lo general, uno soluciona esto con un
-print0
indicador, find
pero dado que hay otras cosas aquí, solo puedo ver soluciones que harían que el comando sea más complicado de lo que vale la pena.
PD: uno de mis sistemas usa un busybox limitado find
que no admite -exec
ni -print0
marcas, y también agrega '/' para denotar directorios, mientras que findutils find no parece, por lo que para esta máquina necesito ejecutar:
dir=<mydir>; (find "$dir" -type f | while read f; do md5sum "$f"; done; find "$dir" -type d | sed 's#/$##') | LC_ALL=C sort | md5sum
Afortunadamente, no tengo archivos / directorios con nuevas líneas en sus nombres, por lo que este no es un problema en ese sistema.