Créez un fichier d'archive tar à la volée et dirigez-le vers md5sum
:
tar c dir | md5sum
Cela produit une seule valeur de hachage MD5 qui doit être unique pour la configuration de votre fichier et de votre sous-répertoire. Aucun fichier n'est créé sur le disque.
Si vous ne vous souciez que des fichiers et non des répertoires vides, cela fonctionne bien :
find /path -type f | sort -u | xargs cat | md5sum
La suggestion d'ire_and_curses d'utiliser tar c <dir>
a quelques problèmes :
- tar traite les entrées de répertoire dans l'ordre dans lequel elles sont stockées dans le système de fichiers, et il n'y a aucun moyen de modifier cet ordre. Cela peut effectivement donner des résultats complètement différents si vous avez le "même" répertoire à différents endroits, et je ne connais aucun moyen de résoudre ce problème (tar ne peut pas "trier" ses fichiers d'entrée dans un ordre particulier).
- Je me soucie généralement de savoir si les numéros groupid et ownerid sont les mêmes, pas nécessairement si la représentation sous forme de chaîne du groupe/propriétaire est la même. Cela correspond à ce que par exemple
rsync -a --delete
fait :il synchronise pratiquement tout (moins xattrs et acls), mais il synchronisera le propriétaire et le groupe en fonction de leur ID, et non de la représentation sous forme de chaîne. Donc, si vous avez synchronisé avec un système différent qui n'a pas nécessairement les mêmes utilisateurs/groupes, vous devez ajouter le--numeric-owner
drapeau à tar - tar inclura le nom de fichier du répertoire que vous vérifiez lui-même, juste quelque chose à savoir.
Tant qu'il n'y a pas de solution pour le premier problème (ou à moins que vous soyez sûr qu'il ne vous affecte pas), je n'utiliserais pas cette approche.
Le find
proposé Les solutions basées sur - ne sont pas non plus utiles car elles n'incluent que des fichiers, pas des répertoires, ce qui devient un problème si la somme de contrôle doit garder à l'esprit les répertoires vides.
Enfin, la plupart des solutions suggérées ne sont pas triées de manière cohérente, car le classement peut être différent d'un système à l'autre.
Voici la solution que j'ai trouvée :
dir=<mydir>; (find "$dir" -type f -exec md5sum {} +; find "$dir" -type d) | LC_ALL=C sort | md5sum
Remarques sur cette solution :
- Le
LC_ALL=C
est d'assurer un ordre de tri fiable entre les systèmes - Cela ne fait pas la différence entre un répertoire "named\nwithanewline" et deux répertoires "named" et "withanewline", mais la probabilité que cela se produise semble très improbable. On corrige généralement cela avec un
-print0
drapeau pourfind
, mais comme il se passe d'autres choses ici, je ne vois que des solutions qui rendraient la commande plus compliquée qu'elle n'en vaut la peine.
PS :un de mes systèmes utilise une busybox limitée find
qui ne prend pas en charge -exec
ni -print0
flags, et il ajoute également '/' pour désigner les répertoires, tandis que findutils find ne semble pas le faire, donc pour cette machine, je dois exécuter :
dir=<mydir>; (find "$dir" -type f | while read f; do md5sum "$f"; done; find "$dir" -type d | sed 's#/$##') | LC_ALL=C sort | md5sum
Heureusement, je n'ai pas de fichiers/répertoires avec des retours à la ligne dans leurs noms, donc ce n'est pas un problème sur ce système.
find /path/to/dir/ -type f -name "*.py" -exec md5sum {} + | awk '{print $1}' | sort | md5sum
La trouvaille La commande répertorie tous les fichiers qui se terminent par .py. La valeur de hachage MD5 est calculée pour chaque fichier .py. AWK est utilisé pour sélectionner les valeurs de hachage MD5 (en ignorant les noms de fichiers, qui peuvent ne pas être uniques). Les valeurs de hachage MD5 sont triées. La valeur de hachage MD5 de cette liste triée est ensuite renvoyée.
J'ai testé cela en copiant un répertoire de test :
rsync -a ~/pybin/ ~/pybin2/
J'ai renommé certains fichiers dans ~/pybin2 .
Le find...md5sum
La commande renvoie la même sortie pour les deux répertoires.
2bcf49a4d19ef9abd284311108d626f1 -
Pour tenir compte de la disposition des fichiers (chemins), afin que la somme de contrôle change si un fichier est renommé ou déplacé, la commande peut être simplifiée :
find /path/to/dir/ -type f -name "*.py" -exec md5sum {} + | md5sum
Sur macOS avec md5
:
find /path/to/dir/ -type f -name "*.py" -exec md5 {} + | md5