web-dev-qa-db-fra.com

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 veux obtenir une seule somme de contrôle MD5 pour tout le contenu d'un répertoire, y compris les fichiers dans les sous-répertoires. Autrement dit, une somme de contrôle combinée constituée de tous les fichiers. Y a-t-il un moyen de faire cela?

183
user17429

La bonne façon dépend exactement de la raison pour laquelle vous demandez:

Option 1: comparer les données uniquement

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 elle-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 ne fonctionne qu'avec BSD find (1), utilisé sous 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 laid:

$ 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 la ligne par le calcul de sort.

Il y a une faiblesse avec cette version de la commande, c'est qu'elle risque de devenir confuse si vous avez des noms de fichiers avec des retours à la ligne, car cela ressemblera à plusieurs lignes à l'appel sort. Le find -s la variante n'a pas ce problème, car la traversée et le tri de l'arborescence ont lieu 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 maintiennent pas les listes de répertoires dans un ordre stable et prévisible. Vous pourriez ne pas vous en rendre compte en utilisant ls et autres, qui trient silencieusement le contenu du répertoire pour vous. L'appel de find sans trier sa sortie d'une manière ou d'une autre entraînera l'ordre des lignes dans la sortie pour correspondre à l'ordre dans lequel le système de fichiers sous-jacent les renvoie, ce qui fera que cette commande donnera une valeur de hachage modifiée si l'ordre des fichiers donné à mesure que l'entrée change, même si les données restent identiques.

Vous pouvez vous demander si le -k 2 bit dans la commande GNU sort 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 laissons tomber cette option, ce qui nous permet d'utiliser la même commande avec les deux GNU et BSD sort. Cependant, réalisez qu'il y a une petite chance (1: 2128 avec MD5) que l'ordre exact des noms de fichiers ne correspond pas à l'ordre partiel que faire sans -k 2 peut donner en cas de collision de hachage. Gardez à l'esprit, cependant, si de si petites chances de discordance importent à votre application, cette approche est probablement hors de question pour vous.

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

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 de hacher les métadonnées de fichier et de répertoire.

Option 2: comparer les données et les métadonnées

Si vous devez être en mesure de détecter que quelque chose dans une arborescence a changé, pas seulement le contenu du fichier, demandez à tar d'emballer le répertoire contenu pour vous, puis envoyez-le à md5sum:

$ tar -cf - somedir | md5sum

Étant donné que tar voit également les autorisations de fichiers, la propriété, etc., cela détectera également les modifications de ces éléments, pas seulement les modifications du contenu des fichiers.

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

Comme avec la méthode basée sur find 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 pourrait bien que dans votre application, vous soyez 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 à la suivante.)

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

215
Warren Young

La somme de contrôle doit être d'une représentation déterministe et non ambiguë des fichiers sous forme de chaîne. Déterministe signifie que si vous placez les mêmes fichiers aux mêmes emplacements, vous obtiendrez le même résultat. Sans ambiguïté signifie que deux ensembles de fichiers différents ont des représentations différentes.

Données et métadonnées

Faire une archive contenant les fichiers est un bon début. Il s'agit d'une représentation non ambiguë (évidemment, puisque vous pouvez récupérer les fichiers en extrayant l'archive). Il peut inclure des métadonnées de fichier telles que les dates et la propriété. Cependant, ce n'est pas encore tout à fait vrai: une archive est ambiguë, car sa représentation dépend de l'ordre dans lequel les fichiers sont stockés et, le cas échéant, de la compression.

Une solution consiste à trier les noms de fichiers avant de les archiver. Si les noms de vos fichiers ne contiennent pas de retours à la ligne, vous pouvez exécuter find | sort pour les répertorier et les ajouter aux archives dans cet ordre. Prenez soin de dire à l'archiveur de ne pas rentrer dans les répertoires. Voici des exemples avec POSIX pax, GNU tar et cpio:

find | LC_ALL=C sort | pax -w -d | md5sum
find | LC_ALL=C sort | tar -cf - -T - --no-recursion | md5sum
find | LC_ALL=C sort | cpio -o | md5sum

Noms et contenus uniquement, la voie low-tech

Si vous souhaitez uniquement prendre en compte les données du fichier et non les métadonnées, vous pouvez créer une archive qui inclut uniquement le contenu du fichier, mais il n'existe aucun outil standard pour cela. Au lieu d'inclure le contenu du fichier, vous pouvez inclure le hachage des fichiers. Si les noms de fichiers ne contiennent pas de sauts de ligne et qu'il n'y a que des fichiers et répertoires normaux (pas de liens symboliques ou de fichiers spéciaux), c'est assez facile, mais vous devez prendre soin de quelques choses:

{ export LC_ALL=C;
  find -type f -exec wc -c {} \; | sort; echo;
  find -type f -exec md5sum {} + | sort; echo;
  find . -type d | sort; find . -type d | sort | md5sum;
} | md5sum

Nous incluons une liste de répertoires en plus de la liste des sommes de contrôle, sinon les répertoires vides seraient invisibles. La liste des fichiers est triée (dans un environnement local spécifique et reproductible - merci à Peter.O de me le rappeler). echo sépare les deux parties (sans cela, vous pourriez créer des répertoires vides dont le nom ressemble à md5sum sortie qui pourrait également passer pour les fichiers ordinaires). Nous incluons également une liste des tailles de fichiers, pour éviter attaques par extension de longueur .

Soit dit en passant, MD5 est obsolète. S'il est disponible, envisagez d'utiliser SHA-2, ou au moins SHA-1.

Noms et données, prenant en charge les nouvelles lignes dans les noms

Voici une variante du code ci-dessus qui repose sur les outils GNU pour séparer les noms de fichier avec des octets nuls. Cela permet aux noms de fichier de contenir des retours à la ligne. Le GNU Les utilitaires digest citent des caractères spéciaux dans leur sortie, il n'y aura donc pas de nouvelles lignes ambiguës.

{ export LC_ALL=C;
  du -0ab | sort -z; # file lengths, including directories (with length 0)
  echo | tr '\n' '\000'; # separator
  find -type f -exec sha256sum {} + | sort -z; # file hashes
  echo | tr '\n' '\000'; # separator
  echo "End of hashed data."; # End of input marker
} | sha256sum

Une approche plus robuste

Voici un script Python qui teste de manière minimale qui construit une table de hachage décrivant une hiérarchie de fichiers. Il prend en compte les répertoires et le contenu des fichiers et ignore les liens symboliques et autres fichiers, et renvoie une erreur fatale si un fichier peut pas lu.

#! /usr/bin/env python
import hashlib, hmac, os, stat, sys
## Return the hash of the contents of the specified file, as a hex string
def file_hash(name):
    f = open(name)
    h = hashlib.sha256()
    while True:
        buf = f.read(16384)
        if len(buf) == 0: break
        h.update(buf)
    f.close()
    return h.hexdigest()
## Traverse the specified path and update the hash with a description of its
## name and contents
def traverse(h, path):
    rs = os.lstat(path)
    quoted_name = repr(path)
    if stat.S_ISDIR(rs.st_mode):
        h.update('dir ' + quoted_name + '\n')
        for entry in sorted(os.listdir(path)):
            traverse(h, os.path.join(path, entry))
    Elif stat.S_ISREG(rs.st_mode):
        h.update('reg ' + quoted_name + ' ')
        h.update(str(rs.st_size) + ' ')
        h.update(file_hash(path) + '\n')
    else: pass # silently symlinks and other special files
h = hashlib.sha256()
for root in sys.argv[1:]: traverse(h, root)
h.update('end\n')
print h.hexdigest()

Jetez un oeil à md5deep . Certaines des fonctionnalités de md5deep qui peuvent vous intéresser:

Opération récursive - md5deep est capable d'examiner récursivement une arborescence de répertoires entière. Autrement dit, calculez le MD5 pour chaque fichier d'un répertoire et pour chaque fichier de chaque sous-répertoire.

Mode de comparaison - md5deep peut accepter une liste de hachages connus et les comparer à un ensemble de fichiers d'entrée. Le programme peut afficher soit les fichiers d'entrée qui correspondent à la liste des hachages connus, soit ceux qui ne correspondent pas.

...

14
faultyserver

Si votre objectif est simplement de trouver des différences entre deux répertoires, envisagez d'utiliser diff.

Essaye ça:

diff -qr dir1 dir2
11
Deepak Mittal

Vous pouvez hacher chaque fichier récursivement puis hacher le texte résultant:

> md5deep -r -l . | sort | md5sum
d43417958e47758c6405b5098f151074 *-

md5deep est requis.

7
Pavel Vlasov

solution :

$ pip install checksumdir
$ checksumdir -a md5 assets/js
981ac0bc890de594a9f2f40e00f13872
$ checksumdir -a sha1 assets/js
88cd20f115e31a1e1ae381f7291d0c8cd3b92fad

fonctionne rapidement et plus facile solution puis bash scripting.

voir doc: https://pypi.python.org/pypi/checksumdir/1.0.5

5
DmitrySemenov

Pour faire suite à cette excellente réponse , si vous souhaitez accélérer le calcul de la somme de contrôle pour un grand répertoire, essayez GNU Parallel :

find -s somedir -type f | parallel -k -n 100 md5 {} | md5

(Il s'agit d'un Mac avec md5, remplacez si nécessaire.)

Le -k L'indicateur est important, il demande à parallel de maintenir l'ordre, sinon la somme globale peut changer run pour s'exécuter même si les fichiers sont tous identiques. -n 100 dit d'exécuter chaque instance de md5 avec 100 arguments, c'est un paramètre que vous pouvez Tweak pour le meilleur temps d'exécution. Voir également -X drapeau de parallel (mais dans mon cas personnel, cela a causé une erreur.)

4
shawkinaw

J'utilise cet extrait pour volumes modérés :

find . -xdev -type f -print0 | LC_COLLATE=C sort -z | xargs -0 cat | md5sum -

et celui-ci pour XXXL :

find . -xdev -type f -print0 | LC_COLLATE=C sort -z | xargs -0 tail -qc100 | md5sum -

3
poige

Contenu du fichier uniquement , à l'exclusion des noms de fichiers

J'avais besoin d'une version qui ne vérifiait que les noms de fichiers car le contenu résidait dans différents répertoires.

Cette version (la réponse de Warren Young) m'a beaucoup aidé, mais ma version de md5sum renvoie le nom du fichier (par rapport au chemin à partir duquel j'ai exécuté la commande), et les noms de dossier étaient différents, donc même si les sommes de contrôle des fichiers individuels correspondaient, la somme de contrôle finale non.

Pour corriger cela, dans mon cas, j'avais juste besoin de supprimer le nom de fichier de chaque ligne de la sortie find (sélectionnez uniquement le premier mot séparé par des espaces en utilisant cut):

find -s somedir -type f -exec md5sum {} \; | cut -d" " -f1 | md5sum
3
Nicole

nix-hash de le gestionnaire de paquets Nix

La commande nix-hash calcule le hachage cryptographique du contenu de chaque chemin et l'imprime sur la sortie standard. Par défaut, il calcule un hachage MD5, mais d'autres algorithmes de hachage sont également disponibles. Le hachage est imprimé en hexadécimal.

Le hachage est calculé sur une sérialisation de chaque chemin: un vidage de l'arborescence du système de fichiers enracinée sur le chemin. Cela permet de hacher les répertoires et les liens symboliques ainsi que les fichiers normaux. Le vidage est au format NAR produit par nix-store --dump. Ainsi, le chemin nix-hash donne le même hachage cryptographique que le chemin nix-store --dump | md5sum.

3
user45756

Une bonne somme de contrôle d'arbre est l'identifiant d'arbre de Git.

Il n'y a malheureusement pas d'outil autonome disponible pour le faire (du moins je ne le sais pas), mais si vous avez Git à portée de main, vous pouvez simplement faire semblant de configurer un nouveau référentiel et ajouter les fichiers que vous souhaitez vérifier à l'index.

Cela vous permet de produire le hachage d'arbre (reproductible) - qui comprend uniquement le contenu, les noms de fichier et certains modes de fichier réduits (exécutable).

2
eckes

Je ne voulais pas de nouveaux exécutables ni de solutions maladroites alors voici mon point de vue:

#!/bin/sh
# md5dir.sh by Camilo Martin, 2014-10-01.
# Give this a parameter and it will calculate an md5 of the directory's contents.
# It only takes into account file contents and paths relative to the directory's root.
# This means that two dirs with different names and locations can hash equally.

if [[ ! -d "$1" ]]; then
    echo "Usage: md5dir.sh <dir_name>"
    exit
fi

d="$(tr '\\' / <<< "$1" | tr -s / | sed 's-/$--')"
c=$((${#d} + 35))
find "$d" -type f -exec md5sum {} \; | cut -c 1-33,$c- | sort | md5sum | cut -c 1-32
1
Camilo Martin

Un script qui est bien testé et prend en charge un certain nombre d'opérations, notamment la recherche de doublons, la comparaison de données et de métadonnées, l'affichage d'ajouts ainsi que les modifications et les suppressions, vous aimerez peut-être Fingerprint .

L'empreinte digitale en ce moment ne produit pas une seule somme de contrôle pour un répertoire, mais un fichier de transcription qui inclut des sommes de contrôle pour tous les fichiers de ce répertoire.

fingerprint analyze

Cela générera index.fingerprint dans le répertoire courant qui inclut les sommes de contrôle, les noms de fichiers et les tailles de fichiers. Par défaut, il utilise à la fois MD5 et SHA1.256.

À l'avenir, j'espère ajouter la prise en charge de Merkle Trees dans Fingerprint, ce qui vous donnera une seule somme de contrôle de niveau supérieur. À l'heure actuelle, vous devez conserver ce fichier pour effectuer la vérification.

1
ioquatix

Bon mot:

find directory -exec md5sum {} \; 2>&1 | sort -k 2 | md5sum

Cela répertorie tous les fichiers et répertoires et obtient md5sum pour chaque. Puis obtient md5sum pour tout.

Tricky bit résolu ici que md5sum n'est pas capable de faire la somme pour un répertoire, mais il nous le dit: md5sum: dir/sub_dir: Is a directory. Nous déplaçons simplement ce message vers une sortie standard.

0
laimison

Faire individuellement pour tous les fichiers de chaque répertoire.

# Calculating
find dir1 | xargs md5sum > dir1.md5
find dir2 | xargs md5sum > dir2.md5
# Comparing (and showing the difference)
paste <(sort -k2 dir1.md5) <(sort -k2 dir2.md5) | awk '$1 != $3'
0
Leandro Lima

La migration vers le format d'archive POSIX affecte GNU Somme de contrôle basée sur Tar

Cette réponse est destinée à être une mise à jour supplémentaire de l'approche de l'utilisation de la sortie Tar pour hacher le contenu des répertoires, comme cela a été proposé (entre autres) dans les excellentes réponses de Warren Young et Gilles il y a quelque temps.

Depuis lors, au moins openSUSE (depuis sa version 12.2) a changé son format par défaut GNU Tar de "GNU tar 1.13.x format" au format (légèrement) supérieur "POSIX 1003.1-2001 (pax)" . Également en amont (parmi les développeurs de GNU Tar) dont ils discutent pour effectuer la même migration, voir par exemple le dernier paragraphe sur cette page du manuel GNU Tar :

Le format par défaut pour GNU tar est défini au moment de la compilation. Vous pouvez le vérifier en exécutant tar --help Et en examinant les dernières lignes de sa sortie. Habituellement, GNU tar est configuré pour créer des archives au format gnu, cependant, la future version passera à posix.

(Cette page donne également un bon aperçu des différents formats d'archives disponibles avec GNU Tar.)

Dans notre cas, où nous tarons le contenu du répertoire et hachons le résultat, et sans prendre de mesures spécifiques, un changement de GNU au format POSIX a les conséquences suivantes:

  • Malgré un contenu de répertoire identique, la somme de contrôle résultante sera différente.

  • Malgré un contenu de répertoire identique, la somme de contrôle résultante sera différente d'une exécution à l'autre si les en-têtes pax par défaut sont utilisés.

Ce dernier vient du fait que le format POSIX (pax) comprend des en-têtes pax étendus qui sont déterminés par une chaîne de formatage par défaut %d/PaxHeaders.%p/%f Dans GNU Tar. Dans cette chaîne) , le spécificateur %p est remplacé par l'ID de processus du processus Tar générateur, qui est bien sûr différent d'une exécution à l'autre. Voir cette section de la GNU Tar manual et en particulier celui-ci pour plus de détails.

À l'heure actuelle, datant du 28/03/2019, il y a un commit accepté en amont qui désamorce ce problème.

Donc, pour pouvoir continuer à utiliser GNU Tar dans le cas d'utilisation donné, je peux recommander les options alternatives suivantes:

  • Utilisez l'option Tar --format=gnu Pour dire explicitement à Tar de générer l'archive dans le "vieux" format. Ceci est obligatoire pour valider les "anciennes" sommes de contrôle.

  • Utilisez le nouveau format POSIX, mais spécifiez explicitement un en-tête pax approprié, par exemple par --pax-option="exthdr.name=%d/PaxHeaders/%f". Cependant, cela rompt la compatibilité descendante avec les "anciens" sommes de contrôle.

Voici un fragment de code Bash que j'utilise régulièrement pour calculer les sommes de contrôle du contenu du répertoire, y compris les métadonnées:

( export LC_ALL=C
  find <paths> ! -type s -print0 |
  sort -z |
  tar cp --format=gnu --numeric-owner \
         --atime-preserve \
         --no-recursion --null --files-from - |
  md5sum --binary; )

Ici, <paths> Est remplacé par une liste séparée par des espaces des chemins de tous les répertoires que je souhaite voir couverts par la somme de contrôle. Le but de l'utilisation des paramètres régionaux C, de la séparation des octets nuls des noms de fichiers et de l'utilisation de la recherche et du tri pour obtenir un ordre indépendant du système de fichiers des fichiers dans l'archive est déjà suffisamment discuté dans d'autres réponses.

Les parenthèses environnantes gardent le paramètre LC_ALL Local dans un sous-shell.

De plus, j'utilise l'expression ! -type s Avec find pour éviter les avertissements de Tar qui se produisent si les fichiers socket font partie du contenu du répertoire: GNU Tar ne fait pas archive sockets. Si vous préférez être informé des sockets ignorés, laissez cette expression de côté.

J'utilise --numeric-owner Avec Tar, pour pouvoir vérifier les sommes de contrôle plus tard, même sur les systèmes, où tous les propriétaires de fichiers ne sont pas connus.

L'option --atime-preserve Pour Tar est mieux omise si l'un des <paths> Se trouve sur un périphérique monté en lecture seule. Sinon, vous serez averti pour chaque fichier dont l'horodatage d'accès Tar n'a pas pu être restauré. Pour l'écriture activée <paths>, J'utilise cette option, eh bien, pour conserver les horodatages d'accès dans les répertoires hachés.

L'option Tar --no-recursion, Qui était déjà utilisée dans proposition Gilles , empêche Tar de descendre de façon récursive dans les répertoires par lui-même, et d'opérer à la place fichier par fichier sur tout ce qui est alimenté par le trié find sortie.

Et enfin, ce n'est pas vrai que j'utilise md5sum: J'utilise en fait sha256sum.

0
Jürgen

J'utilise l'approche suivante pour déterminer si le contenu/les attributs du répertoire ont changé:

cd /path/to/dir; ls -lnAR --time-style=+%s . | md5sum

Si vous souhaitez également suivre les modifications des attributs étendus:

cd /path/to/dir; (ls -lnAR --time-style=+%s .; getfacl -Rns .) | md5sum

Dans des circonstances normales, il n'est pas nécessaire de vérifier le contenu des fichiers car l'heure de modification du fichier indique déjà une modification du contenu du fichier. Cela accélère également toute l'opération.

Remarques:

  • cd/path/to/dir - rend la somme de contrôle résistante à la relocalisation des répertoires
  • -n - rend la somme de contrôle persistante sur tous les systèmes avec un mappage uid/gid différent
  • -A - inclut tous les fichiers, y compris les pointillés (comme -a) sauf. et ..
  • --time-style = +% s - sans cela, les modifications apportées dans la minute qui suit la somme de contrôle peuvent ne pas être suivies, cette sortie est également persistante entre les copies rsync (contrairement à l'option --full-time)

Si vous souhaitez également vérifier le contenu des fichiers: tar c -C /path/to/dir | md5sum Ou avec des attributs étendus: cd /path/to/dir; (tar c .; getfacl -Rns .) | md5sum

Mise à jour:

Afin de le faire fonctionner sur une plus large gamme de systèmes, j'ai dû définir les paramètres régionaux et filtrer également le nombre de liens fixes et les tailles de répertoire de la sortie ls avec awk:

cd /path;LC_ALL=C ls -lnAR --time-style=+%s .|awk '{$2=0;$1~/^d/&&$5=0;print}'|md5sum
0
Alek

Une approche robuste et propre

  • Tout d'abord, ne monopolise pas la mémoire disponible ! Hachez un fichier en morceaux plutôt que d'alimenter le fichier entier.
  • Différentes approches pour différents besoins/objectifs (tous les éléments ci-dessous ou choisissez ce qui s'applique):
    • Hachage uniquement le nom de l'entrée de toutes les entrées de l'arborescence du répertoire
    • Hachez le contenu du fichier de toutes les entrées (en laissant la méta-like, le numéro d'inode, ctime, atime, mtime, size, etc., vous avez l'idée)
    • Pour un lien symbolique, son contenu est le nom du référent. Hachez-le ou choisissez de sauter
    • Suivre ou ne pas suivre (nom résolu) le lien symbolique lors du hachage du contenu de l'entrée
    • S'il s'agit d'un répertoire, son contenu n'est que des entrées de répertoire. Lors de la traversée récursive, ils seront éventuellement hachés, mais les noms d'entrée de répertoire de ce niveau devraient-ils être hachés pour marquer ce répertoire? Utile dans les cas d'utilisation où le hachage est nécessaire pour identifier rapidement un changement sans avoir à parcourir en profondeur pour hacher le contenu. Un exemple serait les changements de nom d'un fichier mais le reste du contenu reste le même et ce sont tous des fichiers assez gros
    • Bien gérer les gros fichiers (encore une fois, faites attention à la RAM)
    • Gérer des arborescences de répertoires très profondes (attention aux descripteurs de fichiers ouverts)
    • Gérer les noms de fichiers non standard
    • Comment procéder avec des fichiers qui sont des sockets, des pipes/FIFO, des périphériques bloc, des périphériques char? Faut-il les hacher aussi?
    • Ne mettez pas à jour le temps d'accès d'une entrée pendant la traversée car cela sera un effet secondaire et contre-productif (intuitif?) Pour certains cas d'utilisation.

C'est ce que j'ai sur ma tête, quiconque a passé un peu de temps à travailler sur ce sujet aurait attrapé d'autres pièges et cas de coin.

Voici un outil (avertissement: j'y contribue) dtreetrawl , très léger sur la mémoire, qui traite la plupart des cas, peut être un peu rude sur les bords mais a été très utile.

Usage:
  dtreetrawl [OPTION...] "/trawl/me" [path2,...]

Help Options:
  -h, --help                Show help options

Application Options:
  -t, --terse               Produce a terse output; parsable.
  -d, --delim=:             Character or string delimiter/separator for terse output(default ':')
  -l, --max-level=N         Do not traverse tree beyond N level(s)
  --hash                    Hash the files to produce checksums(default is MD5).
  -c, --checksum=md5        Valid hashing algorithms: md5, sha1, sha256, sha512.
  -s, --hash-symlink        Include symbolic links' referent name while calculating the root checksum
  -R, --only-root-hash      Output only the root hash. Blank line if --hash is not set
  -N, --no-name-hash        Exclude path name while calculating the root checksum
  -F, --no-content-hash     Do not hash the contents of the file

Un exemple de sortie conviviale pour les humains:

...
... //clipped
...
/home/lab/linux-4.14-rc8/CREDITS
        Base name                    : CREDITS
        Level                        : 1
        Type                         : regular file
        Referent name                :
        File size                    : 98443 bytes
        I-node number                : 290850
        No. directory entries        : 0
        Permission (octal)           : 0644
        Link count                   : 1
        Ownership                    : UID=0, GID=0
        Preferred I/O block size     : 4096 bytes
        Blocks allocated             : 200
        Last status change           : Tue, 21 Nov 17 21:28:18 +0530
        Last file access             : Thu, 28 Dec 17 00:53:27 +0530
        Last file modification       : Tue, 21 Nov 17 21:28:18 +0530
        Hash                         : 9f0312d130016d103aa5fc9d16a2437e

Stats for /home/lab/linux-4.14-rc8:
        Elapsed time     : 1.305767 s
        Start time       : Sun, 07 Jan 18 03:42:39 +0530
        Root hash        : 434e93111ad6f9335bb4954bc8f4eca4
        Hash type        : md5
        Depth            : 8
        Total,
                size           : 66850916 bytes
                entries        : 12484
                directories    : 763
                regular files  : 11715
                symlinks       : 6
                block devices  : 0
                char devices   : 0
                sockets        : 0
                FIFOs/pipes    : 0
0
six-k

Si vous n'avez pas besoin de md5, vous pouvez essayer

find . -type f | xargs cksum | cksum
0
Martin Koubek