ディレクトリの内容のMD5の合計を合計として取得するには?

ディレクトリの内容のMD5の合計を合計として取得するには?

md5sumプログラムはディレクトリのチェックサムを提供しません。サブディレクトリのファイルを含むディレクトリの内容全体の単一のMD5チェックサムを取得したいと思います。つまり、すべてのファイルで構成される結合チェックサムです。これを行う方法はありますか?

ベストアンサー1

正しいアプローチは、質問する正確な理由によって異なります。

オプション1:データのみ比較

ツリーファイルの内容のハッシュのみが必要な場合は、次のことができます。

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

まず、すべてのファイルコンテンツを予測可能な順序で個別に集計してから、ファイル名のリストとMD5ハッシュを渡してハッシュし、ツリーの変更時にファイルコンテンツが変更されたときにのみ変更される値を提供します。

残念ながら、find -sBSD find(1)はmacOS、FreeBSD、NetBSD、およびOpenBSDでのみ機能します。 GNUまたはSUS find(1)システムで同様のものを得るには、もっと醜いことが必要です。

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

このビットはfind -sMD5ハッシュをスキップするように指示するため、計算ではフィールド2のファイル名だけが行末までソートされます。sort-k 2sort

このコマンドバージョンの1つの弱点は、改行文字を含むファイル名があると複数行の呼び出しのように見えるため、簡単に混乱する可能性があることですsort。このfind -sバリエーションは、ツリーの巡回とソートが同じプログラムで発生するため、この問題はありませんfind

どちらの場合も、誤った肯定を避けるために順序が必要です。ほとんどの一般的なUnix / Linuxファイルシステムは、ディレクトリリストを安定した予測可能な順序で維持しません。lsなどを使用して認識できない場合があります。ディレクトリの内容を自動的にソートします。何らかの方法で出力の順序を指定しない呼び出しは、出力の行の順序がデフォルトのファイルシステムが返す順序findと一致します。これにより、ファイルの順序が次のように指定された場合にコマンドが提供されます。入力が変更されます。データが同じでもハッシュ値が変更されました。

-k 2GNUsortコマンドで上記のビットが必要かどうかを尋ねることができます。ファイル名は、内容が変更されない限りファイルデータのハッシュとして適切に表示されるため、このオプションを削除すると偽の肯定が発生しないため、GNUとBSDで同じコマンドを使用できますsort。ただし、ハッシュ競合がある場合、ファイル名の正確な順序がこの操作を実行しない場合、提供された部分順序と一致しない可能性が低くなります(MD5は1:2 128-k 2)。ただし、このような小さな矛盾の可能性がアプリケーションにとって重要な場合は、全体的なアプローチが不可能になる可能性があることに注意してください。

md5sumコマンドをmd5別のハッシュ関数に変更する必要があるかもしれません。別のハッシュ関数を選択してシステムにコマンドの2番目の形式が必要な場合は、sortそれに応じてコマンドを調整する必要があります。別のトラップは、一部のデータ要約プログラムがファイル名をまったく作成しないことです。典型的な例は古いUnixsumプログラムです。

この方法はmd5sumN + 1呼び出しを必要とするので、やや非効率的です。ここで、Nはツリー内のファイル数ですが、これはファイルとディレクトリのメタデータハッシュを防ぐために必要なコストです。

オプション2:データ比較そしてメタデータ

これを検出できる必要がある場合何もないファイルの内容だけでなく、ツリーの内容も変更されました。tarディレクトリの内容を圧縮して、次のアドレスに送信するように依頼してくださいmd5sum

$ tar -cf - somedir | md5sum

ファイル権限、所有権なども表示できるため、tarファイル内容の変更だけでなく、これらの変更も検出します。

この方法は、ツリーを一度だけナビゲートし、ハッシュプログラムを一度だけ実行するので、はるかに高速です。

find上記のベース方法と同様に、tarファイル名はデフォルトのファイルシステムから返された順序で処理されます。おそらく、アプリケーションにはこれが起こらないと確信できる内容があります。この場合、少なくとも3つの異なる使用パターンを考えることができます。 (指定されていない動作領域に入っているため、リストしません。ここにあるすべてのファイルシステムは、オペレーティングシステムのバージョンによって異なる場合があります。)

誤検出が発生した場合は、次のfind | cpioオプションをお勧めします。ザイルズの答え

おすすめ記事