Déterminer si des fichiers ont été ajoutés, supprimés ou modifiés dans un répertoire

StackOverflow https://stackoverflow.com/questions/7325072

Question

Je suis en train d'écrire un script Python qui va obtenir la somme MD5 de tous les fichiers dans un répertoire (sous Linux). Ce que je crois que je l'ai fait dans le code ci-dessous.

Je veux être en mesure d'exécuter ce pour vous assurer qu'aucun des fichiers dans le répertoire ont changé, et aucun fichier n'a été ajouté pour supprimer.

Le problème est de savoir si je fais un changement dans un fichier dans le répertoire mais le changer en arrière. Je reçois un résultat différent de l'exécution de la fonction ci-dessous. (Même si je l'ai changé le dos de fichier modifié.

Quelqu'un peut-il expliquer cela. Et laissez-moi savoir si vous pouvez penser à un travail autour?

def get_dir_md5(dir_path):
    """Build a tar file of the directory and return its md5 sum"""
    temp_tar_path = 'tests.tar'
    t = tarfile.TarFile(temp_tar_path,mode='w')  
    t.add(dir_path)
    t.close()

    m = hashlib.md5()
    m.update(open(temp_tar_path,'rb').read())
    ret_str = m.hexdigest()

    #delete tar file
    os.remove(temp_tar_path)
    return ret_str

Edit: Comme ces bons gens ont répondu, il semble que le goudron contient des informations en-tête comme date de modification. Would en utilisant le travail zip différemment ou un autre format?

D'autres idées pour contournements de travail?

Était-ce utile?

La solution

Comme les autres réponses mentionnées, deux fichiers tar peuvent être différents, même si le contenu sont les mêmes, soit en raison de changements de métadonnées de goudron ou de modifications de commande de fichier. Vous devez exécuter la somme de contrôle sur les données de fichiers directement, trier les listes d'annuaire pour assurer qu'ils sont toujours dans le même ordre. Si vous souhaitez inclure des métadonnées dans la somme de contrôle, inclure manuellement.

Exemple Untested en utilisant os.walk:

import os
import os.path
def get_dir_md5(dir_root):
    """Build a tar file of the directory and return its md5 sum"""

    hash = hashlib.md5()
    for dirpath, dirnames, filenames in os.walk(dir_root, topdown=True):

        dirnames.sort(key=os.path.normcase)
        filenames.sort(key=os.path.normcase)

        for filename in filenames:
            filepath = os.path.join(dirpath, filename)

            # If some metadata is required, add it to the checksum

            # 1) filename (good idea)
            # hash.update(os.path.normcase(os.path.relpath(filepath, dir_root))

            # 2) mtime (possibly a bad idea)
            # st = os.stat(filepath)
            # hash.update(struct.pack('d', st.st_mtime))

            # 3) size (good idea perhaps)
            # hash.update(bytes(st.st_size))

            f = open(filepath, 'rb')
            for chunk in iter(lambda: f.read(65536), b''):
                hash.update(chunk)

    return hash.hexdigest()

Autres conseils

En-têtes de fichier RAT comprennent un champ pour le moment modifié du fichier; l'acte de modifier un fichier, même si ce changement est changé plus tard en arrière, signifie les en-têtes de fichier RAT seront différents, conduisant à différents hash.

Vous n'avez pas besoin de faire le fichier RAT pour faire ce que vous proposez.

Voici votre algorithme de contournement:

  1. Promenade l'arborescence;
  2. Prendre la signature md5 de chaque fichier;
  3. Trier les signatures;
  4. Prendre la signature md5 de la chaîne de texte de toutes les signatures des fichiers individuels.

La seule signature résultante sera ce que vous recherchez.

Heck, vous ne même pas besoin de Python. Vous pouvez faire ceci:

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

Les fichiers tar contiennent des métadonnées au-delà du contenu des fichiers réels, tels que les temps d'accès aux fichiers, les temps de modification, etc. Même si le contenu du fichier ne changent pas, le fichier tar sera en fait différent.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top