shasum
ディレクトリの内容が変更されたかどうかを確認するためにを使用するシェル スクリプトを作成しています。
LinuxとFreeBSDでは、shasum
私がそうした場合と同じ動作をしますshasum <directory>
が、MacOSではshasum
ハッシュが表示されます。ファイルのみ。
フリーBSD
$ shasum CONTENTS/
7f986e5e5289c59db1bba48df92ffe4707830aaa CONTENTS/
リナックス
$ shasum CONTENTS/
7f986e5e5289c59db1bba48df92ffe4707830aaa CONTENTS/
マックOS
$ shasum CONTENTS/
shasum: CONTENTS/:
MacOS でディレクトリのハッシュを計算するにはどうすればよいですか?
試し1: パイプでTARを使用する
使用しようとしましたが、この tar オプションは MacOS では機能しないようです。
tar cO CONTENTS/ | shasum
tar: Option -O is not permitted in mode -c
da39a3ee5e6b4b0d3255bfef95601890afd80709 -
試す2: FIND/EXECを使用する
MacOSとFreeBSDでは一貫していたが、Linuxでは奇妙なハッシュが返された。
find CONTENTS -type f -exec shasum {} \; | sort -k 2 | shasum
リナックス
c2ddb9bc5f543e956f5cdcc76750cb78cc5f26f3
フリーBSD
3ac2a9d4e2fc5d2d2ec3c7f612e680990cc35824
マックOS
3ac2a9d4e2fc5d2d2ec3c7f612e680990cc35824
TARに関するその他の調査結果
tar
フォルダを「アーカイブ」してそれを実行できるので素晴らしいのですが、フォルダ構造を「歩く」shasum
順序がtar
オペレーティングシステム間で一貫性がない何人かのヘルパーがコメントで言及したように、tar
すべてのシステムで同じバージョンの を使用する必要があります。
一例として、システム 1 では次の順序になります。
drwxr-xr-x 0 root wheel 0 27 Jul 07:23 usr/
-rw-r--r-- 0 root wheel 0 27 Jul 07:25 usr/aaa
drwxr-xr-x 0 root wheel 0 27 Jul 07:25 usr/f1/
-rw-r--r-- 0 root wheel 0 27 Jul 07:25 usr/f1/aaa
drwxr-xr-x 0 root wheel 0 27 Jul 07:25 usr/f1/f0/
-rw-r--r-- 0 root wheel 0 27 Jul 07:25 usr/f1/f0/aaa
drwxr-xr-x 0 root wheel 0 27 Jul 07:25 usr/f2/
-rw-r--r-- 0 root wheel 0 27 Jul 07:25 usr/f2/aaa
drwxr-xr-x 0 root wheel 0 27 Jul 07:25 usr/f2/f1/
-rw-r--r-- 0 root wheel 0 27 Jul 07:25 usr/f2/f1/aaa
drwxr-xr-x 0 root wheel 0 27 Jul 07:25 usr/f2/f1/f0/
-rw-r--r-- 0 root wheel 0 27 Jul 07:25 usr/f2/f1/f0/aaa
drwxr-xr-x 0 root wheel 0 27 Jul 07:25 usr/f3/
-rw-r--r-- 0 root wheel 0 27 Jul 07:25 usr/f3/aaa
drwxr-xr-x 0 root wheel 0 27 Jul 07:25 usr/f3/f2/
-rw-r--r-- 0 root wheel 0 27 Jul 07:25 usr/f3/f2/aaa
drwxr-xr-x 0 root wheel 0 27 Jul 07:25 usr/f3/f2/f1/
-rw-r--r-- 0 root wheel 0 27 Jul 07:25 usr/f3/f2/f1/aaa
システム 2 では次の順序になります。
drwxr-xr-x 0 root wheel 0 27 Jul 07:23 usr/
-rw-r--r-- 0 root wheel 0 27 Jul 07:25 usr/aaa
drwxr-xr-x 0 root wheel 0 27 Jul 07:25 usr/f1/
drwxr-xr-x 0 root wheel 0 27 Jul 07:25 usr/f2/
drwxr-xr-x 0 root wheel 0 27 Jul 07:25 usr/f3/
-rw-r--r-- 0 root wheel 0 27 Jul 07:25 usr/f3/aaa
drwxr-xr-x 0 root wheel 0 27 Jul 07:25 usr/f3/f2/
-rw-r--r-- 0 root wheel 0 27 Jul 07:25 usr/f3/f2/aaa
drwxr-xr-x 0 root wheel 0 27 Jul 07:25 usr/f3/f2/f1/
-rw-r--r-- 0 root wheel 0 27 Jul 07:25 usr/f3/f2/f1/aaa
-rw-r--r-- 0 root wheel 0 27 Jul 07:25 usr/f2/aaa
drwxr-xr-x 0 root wheel 0 27 Jul 07:25 usr/f2/f1/
-rw-r--r-- 0 root wheel 0 27 Jul 07:25 usr/f2/f1/aaa
drwxr-xr-x 0 root wheel 0 27 Jul 07:25 usr/f2/f1/f0/
-rw-r--r-- 0 root wheel 0 27 Jul 07:25 usr/f2/f1/f0/aaa
-rw-r--r-- 0 root wheel 0 27 Jul 07:25 usr/f1/aaa
drwxr-xr-x 0 root wheel 0 27 Jul 07:25 usr/f1/f0/
-rw-r--r-- 0 root wheel 0 27 Jul 07:25 usr/f1/f0/aaa
観点からはtar
すべて良好ですが、順序により、shasum
異なるハッシュが生成されます。
結論
shasum
個々のファイル ハッシュをチェックする点では Linux と BSD 間で一貫性がありますが、ディレクトリに関しては、ファイルのソート方法が原因で、MacOS と FreeBSD でのみ一貫性が保たれます。
コマンドを使用してソートを強制するとfind
、一貫性は FreeBSD と MacOS でのみ得られますが、この方法は、すべてのファイルのハッシュを計算してから構造全体のハッシュを計算するのにかなりの時間がかかるため、時間がかかりすぎます。
を使用してtar
一時ファイルを作成し、その後 を実行すると、shasum
Linux と BSD 間で一貫性がないことが判明しました。これは、アーカイブ方法の違いによるものと思われます。
前進する唯一の方法はソリューションを再設計する。
答え1
mtree
あなたが望むツールです。
仮定する:
$ mkdir foo
$ date > foo/date1; sleep 3
$ date > foo/date2; sleep 3
$ date > foo/date3
$ grep . foo/*
foo/date1:Wed Jul 24 16:11:32 PDT 2019
foo/date2:Wed Jul 24 16:11:35 PDT 2019
foo/date3:Wed Jul 24 16:11:38 PDT 2019
$ find . -ls
7318841 0 drwxr-xr-x 3 admin staff 102 Jul 24 16:11 .
7318847 0 drwxr-xr-x 5 admin staff 170 Jul 24 16:11 ./foo
7318849 8 -rw-r--r-- 1 admin staff 29 Jul 24 16:11 ./foo/date1
7318851 8 -rw-r--r-- 1 admin staff 29 Jul 24 16:11 ./foo/date2
7318853 8 -rw-r--r-- 1 admin staff 29 Jul 24 16:11 ./foo/date3
ディレクトリの参照マニフェストを作成しfoo
、次の場所に保存しますfoo.mtree
:
$ mtree -c -K sha256digest -p foo > foo.mtree
次に、そのディレクトリ内の任意のファイルを操作します。
$ touch foo/date3
もう一度実行しmtree
、先ほど作成したマニフェストを渡すと、mtree
何が変更されたかがわかります。
$ mtree -p foo < foo.mtree || echo fail
date3 changed
modification time expected Wed Jul 24 16:11:38 2019 found Wed Jul 24 16:14:00 2019
fail
$ echo '$ date > foo/date2' >> bar
$ mtree -p foo < foo.mtree || echo fail
date2 changed
modification time expected Wed Jul 24 16:11:35 2019 found Wed Jul 24 16:19:40 2019
SHA-256 expected c76a568f08d98c2830f2fdfb42415c3ec15341b8741450d4bbd863f1d5c4c691 found ddcf8d07785bfe4d031a989339835dc3b8b44653019568dcee612c44fc8e2f70
date3 changed
modification time expected Wed Jul 24 16:11:38 2019 found Wed Jul 24 16:14:00 2019
fail
foo
マニフェストの作成後に不足しているファイルや追加されたファイルも報告されます。
$ mv foo/date1 foo/date4
$ mtree -p foo < foo.mtree || echo fail
. changed
modification time expected Wed Jul 24 16:11:38 2019 found Wed Jul 24 16:21:38 2019
date2 changed
modification time expected Wed Jul 24 16:11:35 2019 found Wed Jul 24 16:19:40 2019
SHA-256 expected c76a568f08d98c2830f2fdfb42415c3ec15341b8741450d4bbd863f1d5c4c691 found ddcf8d07785bfe4d031a989339835dc3b8b44653019568dcee612c44fc8e2f70
date3 changed
modification time expected Wed Jul 24 16:11:38 2019 found Wed Jul 24 16:14:00 2019
date4 extra
./date1 missing
fail
答え2
リムリントあなたが望むこと(だと思う)をします。
関連ポイント:
- デフォルトでは SHA を使用しませんが、使用するように指示することができます。
- Homebrew 経由で MacOS にインストールできます。
- デフォルトでは、指定された単一のディレクトリのチェックサムは計算されません。指定された開始点からすべてのディレクトリのチェックサムを計算するように指示すると、そのポイント以下の「重複」ディレクトリを見つけることができます。ただし、副作用として、まさにあなたが求めているようなことも実行されます。
- これは、あなたが探しているものに対して過剰である可能性があり、使用する最適なオプション フラグを見つけるのにしばらく時間がかかるかもしれませんが、非常に堅牢です。
- どのようなフラグを使うか決めるのは難しいかもしれません。ディレクトリのチェックサムを取得するのは簡単ですが、ない他のことを行うには、注意が必要です。(ただし、明確にしておくと、実際には何も変更されません。せいぜい、必要に応じて後で手動で実行して変更できるシェル スクリプトを生成します。必要なのは、探しているディレクトリ チェックサムを提供する JSON および/または CSV 出力ファイルのようです。)
私は bash スクリプトで rmlint を使用して、重複したディレクトリを検索します。以下は、必要なことだけを最低限実行し、それ以外のことはできるだけ行わないコマンドです。
rmlint "base/dir/to/start/from" --see-symlinks --hidden --algorithm=sha256 --types=none,duplicatedirs --no-backup -o csv:log.csv