ディレクトリにファイルが追加、削除、または変更されたかどうかを判断します
質問
ディレクトリ内のすべてのファイルのMD5Sumを(Linuxで)取得するPythonスクリプトを作成しようとしています。以下のコードでやったと思います。
これを実行して、ディレクトリ内のファイルが変更されていないことを確認し、削除するファイルが追加されていないことを確認したいと考えています。
問題は、ディレクトリ内のファイルに変更を加えてから変更した場合です。以下の関数を実行することから、別の結果が得られます。 (変更されたファイルを変更しましたが。
誰もがこれを説明できますか。そして、あなたが仕事のアラウンドを考えることができるかどうか私に知らせてください?
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
編集:これらの素晴らしい人々が答えたように、TARには変更された日付などのヘッダー情報が含まれているようです。 zip作業を使用すると、異なる形式または別の形式がありますか?
周りの仕事のための他のアイデアはありますか?
解決
他の回答が述べたように、TARメタデータの変更または順序の変更によりコンテンツが同じであっても、2つのTARファイルが異なる場合があります。ファイルデータでチェックサムを直接実行し、ディレクトリリストをソートして、常に同じ順序であることを確認する必要があります。チェックサムにメタデータを含めたい場合は、手動で含めてください。
使用されていない例を使用 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()
他のヒント
TARファイルヘッダーには、ファイルの変更された時間のフィールドが含まれています。ファイルを変更する行為は、その変更が後で変更されたとしても、TARファイルヘッダーが異なることを意味し、異なるハッシュにつながります。
あなたが提案することをするためにTARファイルを作成する必要はありません。
これがあなたの回避策アルゴリズムです:
- ディレクトリツリーを歩きます。
- 各ファイルのMD5署名を取得します。
- 署名を並べ替えます。
- 個々のファイルのすべての署名のテキスト文字列のMD5署名を取得します。
結果の署名は、あなたが探しているものになります。
ヘック、あなたはpythonさえ必要ありません。あなたはこれを行うことができます:
find /path/to/dir/ -type f -name *.py -exec md5sum {} + | awk '{print $1}'\
| sort | md5sum
tar
ファイルには、ファイルアクセス時間、変更時間など、実際のファイルコンテンツを超えてメタデータが含まれています。ファイルの内容が変更されなくても、 tar
実際、ファイルは異なります。