145 votes

Comment puis-je calculer une somme de contrôle md5 d’un répertoire ?

J’ai besoin calculer une somme de contrôle md5 sommaire pour tous les fichiers d’un type particulier (*.py par exemple) placé dans un répertoire et tous ses sous-répertoires. Quelle est la meilleure façon de le faire ? Merci.

Les solutions proposées sont très gentils, mais ce n’est pas exactement ce que j’ai besoin. Je suis à la recherche d’une solution obtenir une somme de contrôle analytique unique qui va identifier de manière unique l’annuaire dans son ensemble - y compris le contenu de tous ses sous-répertoires. Merci beaucoup.

171voto

ire_and_curses Points 32802

Créer un fichier d’archive tar à la volée et le tuyau qui à `` :

Il en résulte un md5sum unique qui doit être unique à vos fichiers et sous-répertoires d’installation. Aucun des fichiers ne sont créés sur le disque.

162voto

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

La commande rechercher la liste de tous les fichiers qui se terminent dans .py. Le md5sum est calculée pour chaque .py fichier. awk est utilisé pour ramasser les md5sums (en ignorant les noms de fichiers, qui peut ne pas être unique). Les md5sums sont triés. La somme md5 de cette liste triée est ensuite retourné.

J'ai testé cela par la copie d'un répertoire de test:

rsync -a ~/pybin/ ~/pybin2/

J'ai renommé certains des fichiers dans ~/pybin2.

L' find...md5sum commande renvoie le même résultat pour les deux répertoires.

2bcf49a4d19ef9abd284311108d626f1  -

53voto

Dieter_be Points 375

ire_and_curses la suggestion de l'utilisation de tar c <dir> a certaines questions:

  • de goudron de processus des entrées de répertoire dans l'ordre dans lequel ils sont stockés dans le système de fichiers, et il n'y a aucun moyen de changer cet ordre. Effectivement cela peut donner des résultats complètement différents si vous avez la même arborescence dans des endroits différents, et je ne connais pas de moyen de résoudre ce problème (le goudron ne peut pas "trier" ses fichiers d'entrée dans un ordre particulier).
  • J'ai l'habitude de se soucient de savoir si groupid et ownerid nombres sont les mêmes, pas nécessairement de savoir si la représentation de chaîne de groupe/de la propriétaire sont les mêmes. Ceci est en ligne avec ce que par exemple rsync -a --delete : il synchronise virtuellement tout (moins xattrs et acl), mais la synchronisation de propriétaire et de groupe en fonction de leur ID, et non sur la représentation de chaîne. Donc, si vous avez synchronisé à un autre système qui n'a pas nécessairement les mêmes utilisateurs/groupes, vous devez ajouter l' --numeric-owner drapeau de goudron
  • tar comprendra le nom du répertoire que vous êtes à la vérification elle-même, quelque chose d'être conscient de.

Tant qu'il n'y a pas de solution pour le premier problème (ou si vous êtes sûr qu'il ne vous affecte pas), je ne voudrais pas utiliser cette approche.

L' find en fonction des solutions proposées ci-dessus ne sont pas bons parce qu'ils comprennent uniquement les fichiers, pas les répertoires, qui devient un problème si vous le calcul des sommes de contrôle doivent garder à l'esprit les répertoires vides.

Enfin, la plupart des solutions proposées ne trie pas systématiquement, car le classement peut être différent entre les systèmes.

C'est la solution je suis venu avec:

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

Notes à propos de cette solution:

  • L' LC_ALL=C est d'assurer la fiabilité de l'ordre de tri dans l'ensemble des systèmes
  • Cela ne fait pas de différence entre un répertoire "nommé\nwithanewline" et deux répertoires "nommé" et "withanewline", mais la chance que ça se produisant semble très peu probable. On fixe habituellement avec un -print0 drapeau pour find , mais depuis il y a d'autres choses qui se passent ici, je ne peux que voir les solutions qui permettraient de rendre la commande plus compliqué alors il vaut la peine.

PS: un de mes systèmes d'utilisations limité busybox find qui ne prend pas en charge -exec ni -print0 drapeaux, et aussi il ajoute '/' pour désigner les répertoires, tandis que findutils trouver ne semble pas, donc, pour cette machine, j'ai besoin d'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 sauts de ligne dans leurs noms, ce n'est pas un problème sur le système.

17voto

Simon Guest Points 71

Si vous vous souciez uniquement les fichiers et répertoires non vides, cela fonctionne très bien :

10voto

Michael Shigorin Points 141

À titre surabondant, il y a md5deep(1); Il n’est pas directement applicable en raison de l’exigence de filtre *.py mais devrait faire aussi bien avec Find (1).

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X