GNU/Linux >> Tutoriels Linux >  >> Linux

Comment obtenir la somme Md5 du contenu d'un répertoire en une seule somme ?

Le programme md5sum ne fournit pas de sommes de contrôle pour les répertoires. Je souhaite obtenir une seule somme de contrôle MD5 pour tout le contenu d'un répertoire, y compris les fichiers des sous-répertoires. C'est-à-dire une somme de contrôle combinée composée de tous les fichiers. Existe-t-il un moyen de faire cela ?

Réponse acceptée :

La bonne méthode dépend exactement de la raison pour laquelle vous demandez :

Option 1 :Comparer uniquement les données

Si vous avez juste besoin d'un hachage du contenu du fichier de l'arborescence, cela fera l'affaire :

$ find -s somedir -type f -exec md5sum {} ; | md5sum

Cela résume d'abord tout le contenu du fichier individuellement, dans un ordre prévisible, puis passe cette liste de noms de fichiers et de hachages MD5 à hacher lui-même, donnant une valeur unique qui ne change que lorsque le contenu de l'un des fichiers de l'arborescence change.

Malheureusement, find -s fonctionne uniquement avec BSD find(1), utilisé dans macOS, FreeBSD, NetBSD et OpenBSD. Pour obtenir quelque chose de comparable sur un système avec GNU ou SUS find(1), vous avez besoin de quelque chose d'un peu plus moche :

$ find somedir -type f -exec md5sum {} ; | sort -k 2 | md5sum

Nous avons imité le comportement de BSD find -s en ajoutant un appel à sort . Le -k 2 bit lui dit de sauter le hachage MD5, donc il ne trie que les noms de fichiers, qui sont dans le champ 2 jusqu'à la fin de ligne par sort compte.

Il y a une faiblesse avec cette version de la commande, c'est qu'elle est susceptible d'être confuse si vous avez des noms de fichiers avec des retours à la ligne, car cela ressemblera à plusieurs lignes pour le sort appel. Le find -s variant n'a pas ce problème, car la traversée de l'arbre et le tri se produisent dans le même programme, find .

Dans les deux cas, le tri est nécessaire pour éviter les faux positifs :les systèmes de fichiers Unix/Linux les plus courants ne conservent pas les listes de répertoires dans un ordre stable et prévisible. Vous ne vous en rendez peut-être pas compte en utilisant ls et autres, qui trient silencieusement le contenu du répertoire pour vous. Appel de find sans trier sa sortie d'une manière ou d'une autre, l'ordre des lignes dans la sortie correspondra à l'ordre dans lequel le système de fichiers sous-jacent les renvoie, ce qui amènera cette commande à donner une valeur de hachage modifiée si l'ordre des fichiers qui lui sont donnés en entrée change, même si les données restent identiques.

Vous pouvez vous demander si le -k 2 bit dans le GNU sort commande ci-dessus est nécessaire. Étant donné que le hachage des données du fichier est un proxy adéquat pour le nom du fichier tant que le contenu n'a pas changé, nous n'obtiendrons pas de faux positifs si nous supprimons cette option, ce qui nous permet d'utiliser la même commande avec GNU et BSD sort . Cependant, sachez qu'il y a une petite chance (1:2 avec MD5) que l'ordre exact des noms de fichiers ne corresponde pas à l'ordre partiel qui se passe de -k 2 peut donner s'il y a jamais une collision de hachage. Gardez à l'esprit, cependant, si de si petites chances d'incompatibilité sont importantes pour votre application, toute cette approche est probablement hors de question pour vous.

En relation :Dans un environnement vide, comment les exécutables sont-ils trouvés ?

Vous devrez peut-être modifier le md5sum commandes à md5 ou une autre fonction de hachage. Si vous choisissez une autre fonction de hachage et que vous avez besoin de la deuxième forme de la commande pour votre système, vous devrez peut-être ajuster le sort commande en conséquence. Un autre piège est que certains programmes de sommation de données n'écrivent pas du tout de nom de fichier, un excellent exemple étant l'ancien Unix sum programme.

Cette méthode est quelque peu inefficace, appelant md5sum N+1 fois, où N est le nombre de fichiers dans l'arborescence, mais c'est un coût nécessaire pour éviter le hachage des métadonnées des fichiers et des répertoires.

Option 2 :Comparer les données et Métadonnées

Si vous devez être en mesure de détecter ce n'importe quoi dans un arbre a changé, pas seulement le contenu du fichier, demandez tar pour emballer le contenu du répertoire pour vous, puis l'envoyer à md5sum :

$ tar -cf - somedir | md5sum

Parce que tar voit également les autorisations de fichiers, la propriété, etc., cela détectera également les modifications apportées à ces éléments, pas seulement les modifications apportées au contenu des fichiers.

Cette méthode est considérablement plus rapide, car elle ne fait qu'un seul passage sur l'arbre et n'exécute le programme de hachage qu'une seule fois.

Comme avec le find méthode basée ci-dessus, tar va traiter les noms de fichiers dans l'ordre dans lequel le système de fichiers sous-jacent les renvoie. Il se peut que dans votre application, vous puissiez être sûr que cela ne se produira pas. Je peux penser à au moins trois modèles d'utilisation différents où cela est susceptible d'être le cas. (Je ne vais pas les énumérer, car nous entrons dans un territoire de comportement non spécifié. Chaque système de fichiers peut être différent ici, même d'une version de l'OS à l'autre.)

Si vous obtenez des faux positifs, je vous recommande d'utiliser le find | cpio option dans la réponse de Gilles.


Linux
  1. Comment trouver le type d'un fichier Img et le monter ?

  2. Trouver l'âge du fichier le plus ancien sur une ligne ou renvoyer zéro ?

  3. Comment obtenir la taille de tar.gz dans le fichier (Mo) en python

  4. Comment obtenir le répertoire absolu d'un fichier dans bash ?

  5. Comment obtenir uniquement le nombre de lignes d'un fichier

Comment obtenir la date et l'heure actuelles en Python

Comment afficher le contenu d'une archive ou d'un fichier compressé sous Linux

Comment obtenir le nom de fichier à partir du chemin complet sous Linux

Comment puis-je trouver l'emplacement MySQL my.cnf

Comment obtenir la taille physique d'un fichier sous Linux ?

Comment trouver le fichier .pid pour un processus donné