ディレクトリのコンテンツのMD5合計を1つの合計として取得するにはどうすればよいですか?


171

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

回答:


186

正しい方法は、あなたが尋ねている正確な理由に依存します:

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

ツリーのファイル内容のハッシュが必要な場合、これでうまくいきます:

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

これは、最初にすべてのファイルの内容を予測可能な順序で個別に要約し、次にファイル名とMD5ハッシュのリストをハッシュしてそれ自体をハッシュし、ツリー内のファイルの1つの内容が変更されたときにのみ変更される単一の値を与えます。

残念ながら、find -smacOS、FreeBSD、NetBSD、OpenBSDで使用されるBSD find(1)でのみ動作します。GNUまたはSUS find(1)を備えたシステムで同等のものを取得するには、少しbitいものが必要です。

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

find -s呼び出しに置き換えましたsort。この-k 2ビットは、MD5ハッシュをスキップするように指示しているため、フィールド2から行末までのファイル名のみを、sort推測によってソートします。

このバージョンのコマンドには弱点があります。ファイル名に改行が含まれていると混乱する可能性がありsortます。これは、呼び出しに対して複数行のように見えるためです。find -sツリーのトラバースとソートは同じプログラム内で行われるため、バリアントにはこの問題はありませんfind

どちらの場合でも、誤検知を避けるためにソートが必要です。最も一般的なUnix / Linuxファイルシステムは、安定した予測可能な順序でディレクトリリストを維持しません。lsディレクトリの内容をサイレントにソートするを使用することでこれを実現できないかもしれません。findなし、-sまたはsort呼び出しは、基礎となるファイルシステムが返す順序でファイルを出力します。入力としてファイルに与えられた順序が変わると、このコマンドは変更されたハッシュ値を与えます。

md5sumコマンドmd5または他のハッシュ関数を変更する必要がある場合があります。別のハッシュ関数を選択し、システムにコマンドの2番目の形式が必要な場合は、sortそれに応じてコマンドを調整する必要があります。もう1つの落とし穴は、一部のデータ集計プログラムがファイル名をまったく書き出さないことsumです。これは、古いUnix プログラムが主な例です。

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

オプション2:データメタデータ比較する

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

$ tar -cf - somedir | md5sum

のでtar等もファイルのアクセス権、所有権を、見て、これはまたそれらのものへの変更を検出します、ただ内容をファイルに変更はありません。

この方法は、ツリーを1回だけ通過し、ハッシュプログラムを1回だけ実行するため、かなり高速です。

find上記のベースのメソッドと同様に、基にtarなるファイルシステムが返す順にファイル名を処理します。アプリケーションで、これが発生しないことを確認できます。少なくとも3つの異なる使用パターンが考えられます。(私たちは不特定の動作領域に入るため、それらをリストするつもりはありません。各ファイルシステムは、OSのバージョンによっても、ここでは異なる場合があります。)

検知が発生しているfind | cpio場合は、Gillesの回答のオプションを選択することをお勧めします。


7
比較するディレクトリに移動して、のfind .代わりに使用するのが最善だと思いますfind somedir。このように、異なるパス指定を指定して検索する場合、ファイル名は同じです。これには注意が必要です:
Abbafei 14年

ファイルもソートする必要がありますか?
CMCDragonkai

@CMCDragonkai:どういう意味ですか?最初のケースでは、我々はないファイル名のリストを並べ替えます。強調の一部ため、2番目のケースでは、我々は意図的にしないでください何も最初の文では、あなたが何かをソートしたくないので、ディレクトリ内のファイルの順序は、変更されたことです。
ウォーレンヤング

@WarrenYoungオプション2が常に優れているわけではない理由をもう少し詳しく説明できますか?それは、より速く、よりシンプルで、よりクロスプラットフォームなようです。どの場合、オプション1にすべきではありませんか?
ロビンウィンスロー

オプション1の代替:find somedir -type f -exec sh -c "openssl dgst -sha1 -binary {} | xxd -p" \; | sort | openssl dgst -sha1すべてのファイル名を無視する(改行で動作するはずです)
windm

38

チェックサムは、文字列としてのファイルの明確で明確な表現である必要があります。確定的とは、同じ場所に同じファイルを配置すると、同じ結果が得られることを意味します。明確なとは、2つの異なるファイルセットが異なる表現を持つことを意味します。

データとメタデータ

ファイルを含むアーカイブを作成することは良い出発点です。これは明確な表現です(明らかに、アーカイブを抽出することでファイルを回復できるため)。日付や所有権などのファイルメタデータが含まれる場合があります。ただし、これはまだ適切ではありません。アーカイブの表現は、ファイルの保存順序に依存するため、また圧縮に該当する場合、アーカイブはあいまいです。

解決策は、アーカイブする前にファイル名をソートすることです。ファイル名に改行が含まれていない場合は、実行find | sortしてそれらをリストし、この順序でアーカイブに追加できます。アーカイバがディレクトリに再帰しないように注意してください。POSIX pax、GNU tarおよび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

名前と内容のみ、ローテクな方法

メタデータではなくファイルデータのみを考慮したい場合は、ファイルコンテンツのみを含むアーカイブを作成できますが、そのための標準ツールはありません。ファイルの内容を含める代わりに、ファイルのハッシュを含めることができます。ファイル名に改行が含まれておらず、通常のファイルとディレクトリのみが存在する場合(シンボリックリンクまたは特殊ファイルはない)、これはかなり簡単ですが、いくつかの点に注意する必要があります。

{ 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

チェックサムのリストに加えて、ディレクトリのリストを含めます。そうしないと、空のディレクトリが見えなくなります。ファイルリストは並べ替えられます(特定の再現可能なロケールで— Peter.Oに思い出させてくれてありがとう)。echo2つの部分を分離します(これがないとmd5sum、通常のファイルにも渡すことができる出力のような名前の空のディレクトリを作成できます)。また、長さ拡張攻撃を回避するために、ファイルサイズのリストを含めます。

ところで、MD5は非推奨です。使用可能な場合は、SHA-2、または少なくともSHA-1の使用を検討してください。

名前とデータ、名前の改行をサポート

以下は、GNUツールに依存してファイル名をヌルバイトで区切る上記のコードの変形です。これにより、ファイル名に改行を含めることができます。GNUダイジェストユーティリティは、出力で特殊文字を引用するため、あいまいな改行はありません。

{ 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

より堅牢なアプローチ

以下は、ファイルの階層を記述するハッシュを作成する最小限のテスト済みPythonスクリプトです。ディレクトリとファイルの内容をアカウントに取り込み、シンボリックリンクと他のファイルを無視し、ファイルを読み取れない場合は致命的なエラーを返します。

#! /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()

OK、これは動作します、ありがとう。しかし、メタデータを含めずにそれを行う方法はありますか?今のところ、実際のコンテンツにのみ必要です。

LC_ALL=C sort異なる環境からのチェックはどうですか...(+1 btw)
Peter.O

このためにPythonプログラム全体を作成しましたか?ありがとう!これは私が予想していた以上のものです。:-)とにかく、これらのメソッドとWarrenの新しいオプション1をチェックします。

いい答えだ。LC_ALL=C複数のマシンおよびOSで実行している場合、並べ替え順序の設定は不可欠です。
デイバーCubranic

どういうcpio -o -意味ですか?cpioはデフォルトでstdin / outを使用しませんか?GNU cpio 2.12プロデュースcpio: Too many arguments
Jan Tojnar

12

見ていmd5deepを。md5deepのいくつかの機能に興味があるかもしれません:

再帰的操作-md5deepは、ディレクトリツリー全体を再帰的に検査できます。つまり、ディレクトリ内のすべてのファイルおよびすべてのサブディレクトリ内のすべてのファイルのMD5を計算します。

比較モード-md5deepは、既知のハッシュのリストを受け入れ、それらを一連の入力ファイルと比較できます。プログラムは、既知のハッシュのリストに一致する入力ファイルまたは一致しない入力ファイルを表示できます。

...


いいですが、それを動作させることができません、それは言う.../foo: Is a directory、何が得られますか?
カミロマーティン14年

3
md5deep自体は、統合されたmd5sumを出力しないため、OPの問題を解決しません。ディレクトリ内の各ファイルのmd5sumを出力するだけです。とはいえ、md5deepの出力をmd5sumすることができます-OPが望んでいたものとはまったく異なりますが、近いです!たとえば、現在のディレクトリの場合:(md5deep -r -l -j0 . | md5sumここ-rで再帰的であり、-l2つのディレクトリの内容を比較するときにファイルの絶対パスが干渉しないように「相対パスを使用」を-j0意味します。個々のmd5sumが異なる順序で返されます)。
スティービー

パス内のいくつかのファイル/ディレクトリを無視する方法は?
サンディーパンナス

9

2つのディレクトリ間の違いを見つけることだけが目的の場合は、diffの使用を検討してください。

これを試して:

diff -qr dir1 dir2

はい、これも便利です。そのコマンドでdir1 dir2を意味したと思います。

1
回避できる場合は通常GUIを使用しませんが、ディレクトリの差分処理にはkdiff3が優れており、多くのプラットフォームで動作します。
正弦波

このコマンドでは、異なるファイルも報告されます。
セルジュStroobandt 14

7

すべてのファイルを再帰的にハッシュし、結果のテキストをハッシュできます。

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

md5deepが必要です。


1
md5deepパッケージはhashdeepの単なる移行ダミーであるため、ubuntu 16.04 でmd5deep使用する代わりにhashdeep
パリク

1
hashdeepを試しました。ハッシュだけでなく## Invoked from: /home/myuser/dev/、現在のパスとを含むヘッダーも出力します## $ hashdeep -s -r -l ~/folder/。これはソートするようになったため、現在のフォルダーまたはコマンドラインを変更すると、最終的なハッシュが異なります。
truf

3

ファイルの内容のみ、ファイル名を除く

内容が異なるディレクトリにあるため、ファイル名のみをチェックするバージョンが必要でした。

このバージョン(ウォーレンヤングの答え)は大いに役立ちましたが、私のバージョンでmd5sumはファイル名(コマンドを実行したパスに関連する)が出力され、フォルダー名が異なっていたため、個々のファイルのチェックサムが一致しても最終チェックサムは一致しませんでした't。

これを修正するには、私の場合、find出力の各行からファイル名を取り除く必要がありました(スペースで区切られた最初の単語のみを選択しますcut)。

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

再現可能なリストを取得するには、チェックサムも並べ替える必要がある場合があります。
16年

3

解決策

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

作品の高速かつ簡単に次いでこの溶液のbashスクリプトを。

ドキュメントを参照してください:https : //pypi.python.org/pypi/checksumdir/1.0.5


pipがない場合は、yum -y install python-pip(またはdnf / apt-get)でインストールする必要がある場合があります
DmitrySemenov

3

nix-hashニックスパッケージマネージャ

コマンドnix-hashは、各パスのコンテンツの暗号化ハッシュを計算し、標準出力に出力します。デフォルトでは、MD5ハッシュを計算しますが、他のハッシュアルゴリズムも利用できます。ハッシュは16進数で出力されます。

ハッシュは、各パスのシリアル化(パスをルートとするファイルシステムツリーのダンプ)で計算されます。これにより、通常のファイルと同様にディレクトリとシンボリックリンクをハッシュできます。ダンプは、nix-store --dumpによって生成されるNAR形式です。したがって、nix-hashパスはnix-store --dump path |と同じ暗号化ハッシュを生成します。md5sum。


2

私はこのスニペットを中程度のボリュームに使用します:

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

そして、これはXXXL用です:

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


-xdevフラグは何をしますか?
czerasz

次のように入力する必要があります:man findそして、その素晴らしいマニュアルを読む;)
poige

いい視点ね :-)。-xdev Don't descend directories on other filesystems.
-czerasz

1
これは、新しい空のファイルを無視することに注意してください(ファイルに触れた場合など)。
ロンジョン

これにより、まったく異なるファイルおよびディレクトリ構造で同じmd5sumが生成される場合が多くあります。ファイルとディレクトリの名前を変更しても、ファイルの並べ替え順序が変更されない場合、それはまったく変更されません。したがって、このアプローチはお勧めしません。
ハンス-ピーターステアー

2

優れたツリーチェックサムは、GitのツリーIDです。

残念ながら、それを実行できるスタンドアロンツールはありません(少なくとも私にはわかりません)が、Gitが手元にある場合は、新しいリポジトリをセットアップして、インデックスにチェックするファイルを追加するふりをすることができます。

これにより、(再現可能な)ツリーハッシュを生成できます。これには、コンテンツ、ファイル名、およびいくつかの縮小ファイルモード(実行可能ファイル)のみが含まれます。


2

この優れた答えのフォローアップとして、大きなディレクトリのチェックサムの計算を高速化したい場合は、GNU Parallelを試してください:

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

(これはMacを使用しておりmd5、必要に応じて交換してください。)

-kフラグは重要です。このフラグはparallel順序を維持するよう指示します。そうしないと、ファイルがすべて同じであっても、全体の合計が実行を変更する可能性があります。100個の引数での-n 100各インスタンスを実行するようにmd5指示されていますが、これは最適な実行時間に調整できるパラメーターです。の-Xフラグも参照してくださいparallel(ただし、個人的なケースではエラーが発生しました)。


1

十分にテストされ、重複の検索、データとメタデータの両方の比較、追加と変更および削除の表示を含む多くの操作をサポートするスクリプトは、指紋が好きかもしれません。

現在、指紋はディレクトリの単一のチェックサムを生成するのではなく、そのディレクトリ内のすべてのファイルのチェックサムを含むトランスクリプトファイルを生成します。

fingerprint analyze

これによりindex.fingerprint、チェックサム、ファイル名、ファイルサイズを含む現在のディレクトリに生成されます。デフォルトでは、MD5との両方を使用しますSHA1.256

将来的には、指紋にMerkle Treeのサポートを追加して、単一のトップレベルチェックサムを提供したいと考えています。現時点では、検証を行うためにそのファイルを保持する必要があります。


1

私は新しい実行可能ファイルや不格好なソリューションが欲しくなかったので、ここに私の見解を示します。

#!/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

0

堅牢でクリーンなアプローチ

  • まず最初に、利用可能なメモリを独占しないください!ファイル全体をフィードするのではなく、チャンク単位でファイルをハッシュします。
  • さまざまなニーズ/目的のためのさまざまなアプローチ(以下のすべてまたは適用するものを選択してください):
    • ディレクトリツリー内のすべてのエントリのエントリ名のみをハッシュする
    • すべてのエントリのファイルの内容をハッシュします(メタデータ、iノード番号、ctime、atime、mtime、サイズなどを残して、アイデアを得ます)
    • シンボリックリンクの場合、そのコンテンツは参照先名です。ハッシュするか、スキップすることを選択します
    • エントリのコンテンツをハッシュしながら、シンボリックリンクをフォローするかどうか(解決された名前)
    • ディレクトリの場合、その内容は単なるディレクトリエントリです。再帰的にトラバースする間、それらは最終的にハッシュされますが、そのレベルのディレクトリエントリ名をハッシュしてこのディレクトリをタグ付けする必要がありますか?内容をハッシュするために深くトラバースする必要なく、変更を迅速に識別するためにハッシュが必要なユースケースで役立ちます。例としては、ファイル名の変更がありますが、残りのコンテンツは同じままで、すべてかなり大きなファイルです
    • 大きなファイルを適切に処理する(もう一度、RAMに注意する)
    • 非常に深いディレクトリツリーを処理する(開いているファイル記述子に注意する)
    • 非標準のファイル名を処理する
    • ソケット、パイプ/ FIFO、ブロックデバイス、charデバイスであるファイルを処理する方法 それらもハッシュする必要がありますか?
    • トラバース中にエントリのアクセス時間を更新しないでください。これは、特定のユースケースでは副作用であり、逆効果(直感的?)になるためです。

これは私が私の頭の上に持っているものであり、実際にこれに時間を費やした人は他の落とし穴やコーナーケースを捕まえていたでしょう。

ここにツールがあります(免責事項:私はそれに貢献しています)dtreetrawlは、ほとんどの場合に対処するメモリ上で非常に軽く、エッジの周りが少し荒いかもしれませんが、非常に役立ちました。

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

人間に優しい出力の例:

...
... //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

一般的なアドバイスはいつでも歓迎しますが、最良の回答は具体的であり、必要に応じてコードを使用します。参照したツールの使用経験がある場合は、それを含めてください。
bu5hman

@ bu5hman確かに!私はその開発に関与しているので、それがどれほどうまく機能するかについてもっと言うことは非常に快適ではありませんでした。
6 k

0

各ディレクトリ内のすべてのファイルに対して個別に行う。

# 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

POSIXアーカイブ形式への移行は、GNU Tarベースのチェックサムに影響します

この回答は、先ほどウォーレンヤングジルの優れた回答で提案されていたように、Tar出力を使用してディレクトリのコンテンツをハッシュするアプローチの補足更新を目的としています。

それ以降、少なくともopenSUSE(リリース12.2以降)は、デフォルトのGNU Tar形式を「GNU tar 1.13.x形式」から(わずかに)優れた「POSIX 1003.1-2001(pax)形式」に変更しました。また、上流(GNU Tarの開発者の中で)彼らは同じ移行を実行するために議論します。例えば、GNU Tarマニュアルのこのページの最後の段落を見てください

GNU tarのデフォルト形式は、コンパイル時に定義されます。を実行してtar --help、出力の最後の行を調べることで確認できます。通常、GNU tarはgnu形式でアーカイブを作成するように構成されていますが、将来のバージョンはに切り替わりposixます。

(このページは、GNU Tarで利用可能なさまざまなアーカイブ形式についての素晴らしいレビューも提供します。)

私たちの場合、ディレクトリの内容をtarし、結果をハッシュし、特定の措置を講じることなく、GNUからPOSIX形式への変更は次の結果をもたらします。

  • 同じディレクトリ内容にもかかわらず、結果のチェックサムは異なります。

  • ディレクトリーの内容が同一であるにもかかわらず、デフォルトのpaxヘッダーが使用されている場合、結果のチェックサムは実行ごとに異なります。

後者は、POSIX(pax)形式にはデフォルトの%d/PaxHeaders.%p/%fGNU Tarの形式文字列によって決定される拡張paxヘッダーが含まれているという事実に由来しています。この文字列内で、指定子%pは生成するTarプロセスのプロセスIDに置き換えられます。これはもちろん実行ごとに異なります。参照してください。このセクションGNUタールマニュアル、特にこの1詳細については、を。

ちょうど今、2019-03-28から、この問題を解消するコミットがアップストリームで受け入れられています。

そのため、特定のユースケースでGNU Tarを引き続き使用できるようにするには、次の代替オプションをお勧めします。

  • Tarオプション--format=gnuを使用して、「古い」形式でアーカイブを生成するようTarに明示的に指示します。これは、「古い」チェックサムを検証するために必須です。

  • 新しいPOSIX形式を使用しますが、適切なpaxヘッダーを明示的に指定します(例:)--pax-option="exthdr.name=%d/PaxHeaders/%f"。ただし、これにより、「古い」チェックサムに対する下位互換性が失われます。

これは、メタデータを含むディレクトリコンテンツのチェックサムを計算するために定期的に使用するBashコードフラグメントです。

( 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; )

ここで<paths>は、チェックサムでカバーしたいすべてのディレクトリのパスのスペース区切りリストに置き換えられます。Cロケールを使用する目的、ファイル名のヌルバイト区切り、およびアーカイブ内のファイルのファイルシステムに依存しない順序を取得するために検索と並べ替えを使用する目的は、他の回答ですでに十分に説明されています。

周囲の括弧は、LC_ALL設定をサブシェル内でローカルに保ちます。

さらに、ソケットファイルがディレクトリの内容の一部である場合に発生するTarからの警告を回避するために式! -type swith を使用しfindます。GNUTarはソケットをアーカイブしません。スキップされたソケットに関する通知を希望する場合は、その式を残します。

私は--numeric-ownerTar を使用して、ファイル所有者のすべてが知られていないシステムでもチェックサムを後で検証できるようにします。

--atime-preserveTar のオプションは<paths>、読み取り専用でマウントされたデバイス上にある場合は省略したほうがよいでしょう。そうしないと、アクセスタイムスタンプTarが復元できなかった個々のファイルごとに警告が表示されます。書き込み可能の<paths>場合、このオプションを使用して、ハッシュされたディレクトリのアクセスタイムスタンプを保持します。

Gillesの提案--no-recursionすでに使用されているTarオプションは、Tar が単独でディレクトリに再帰的に下降することを防ぎ、代わりにソートされた出力から供給されるものをファイルごとに操作することを防ぎます。find

最後に、私が使用しているのは正しくありません。md5sum実際に使用していますsha256sum


弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.