是否有像 diff -r 這樣的工具可以使用雜湊值將目錄樹與清單檔案進行比較?

是否有像 diff -r 這樣的工具可以使用雜湊值將目錄樹與清單檔案進行比較?

這是我的情況。我有兩個冷存儲存檔卷(應該)包含相同的資料集。這些磁碟區包含不經常存取的備份。我擔心,最終,bitrot 會到達其中一個或兩個,並巧妙地破壞其中包含的資料。我知道我可以diff -r兩個卷並找到兩個卷之間已更改或消失的文件,但我沒有得到任何有關哪個卷具有“良好”副本的有用指示。這些是 USB 磁碟,將它們轉換為 ZFS 之類的東西似乎……很繁重。

我想要的是一個工具,它將遞歸地遍歷目錄樹並編寫一個清單文件,其中包含路徑和文件名以及文件內容的哈希值。我會在將資料寫入每個磁碟區後立即運行此工具,並將生成的清單檔案儲存在熱儲存上,也許處於某種修訂控制之下。

我希望能夠從這個文件中運行一些完全一樣的東西diff -r——它會告訴我文件是否被添加、刪除或其內容是否更改。只是它不會將一個卷與另一個卷進行比較,而是將一個卷與已知良好的清單文件進行比較。使用這種方法,我應該能夠判斷未來數月/數年從磁碟讀取的資料是否與我最初放入磁碟的資料相同。

我不得不認為這樣的事情已經存在了。我可以使用以下方法來獲得近似清單檔案的內容:

find /mnt/my-volume -type f -exec md5sum {} + > manifest.txt

但到目前為止,我還沒有想出一個好方法來解析這個檔案並遞歸地檢查每個雜湊值。另外,不太重要的是,這不會告訴我空目錄是否出現或消失。 (我想不出為什麼這很重要,但很高興知道它發生了。)

我是否走在正確的軌道上,或者是否有更合適的工具來完成此類事情?

答案1

你是對的,這樣的工具確實已經存在。雖然我看到您的帖子被標記為“linux”,但也許面向 BSD 的解決方案會很有啟發。

FreeBSD 的 mtree(8) 實用程序可以完全按照你的要求做。

認為:

$ find .
.
./c
./c/file3
./b
./b/file2
./a
./a/file1

要建立該檔案層次結構的清單(包括每個檔案的 sha256 雜湊值),需要:

$ mtree -c -K sha256 > /tmp/manifest.txt
$ cat /tmp/manifest.txt
#          user: diego
#       machine: myhost.example.com
#          tree: /data/home/diego/foo
#          date: Wed Mar 28 10:31:17 2018

# .
/set type=file uid=1001 gid=1001 mode=0710 nlink=1 flags=uarch
.               type=dir nlink=5 time=1522257963.738221000

# ./a
/set type=file uid=1001 gid=1001 mode=0600 nlink=1 flags=uarch
a               type=dir mode=0710 nlink=2 time=1522257932.680802000
    file1       size=29 time=1522257932.682389000 \
                sha256digest=6b4114c4f12e63c0ca44073de5ca0a2b39fedaceaa533af3dfdc89f00039c973
# ./a
..


# ./b
b               type=dir mode=0710 nlink=2 time=1522257937.929131000
    file2       size=29 time=1522257937.930666000 \
                sha256digest=9f7a0a49475bb6f98e609a4e057f0bc702c5e4706be5bd656a676fd8d15da7ef
# ./b
..


# ./c
c               type=dir mode=0710 nlink=2 time=1522257942.064315000
    file3       size=29 time=1522257942.065882000 \
                sha256digest=bd617f47217ef0605d3aff036778d10bf18cb2f415c45e8e362e2c091df19491
# ./c
..

然後,可以透過將清單管道傳輸到 mtree 來根據清單驗證檔案層次結構:

$ mtree < /tmp/manifest.txt || echo fail

新增、刪除、重新命名或修改檔案都會導致驗證失敗:

$ touch foo
$ mtree < /tmp/manifest.txt || echo fail
.:      modification time (Wed Mar 28 10:34:56 2018, Wed Mar 28 10:37:01 2018)
extra: foo
fail
$ rm foo; touch b/file2; mtree < /tmp/manifest.txt || echo fail
.:      modification time (Wed Mar 28 10:34:56 2018, Wed Mar 28 10:39:39 2018)
b/file2: 
        modification time (Wed Mar 28 10:25:37 2018, Wed Mar 28 10:39:39 2018)
fail
$ mv c/file3 c/FILE3; rm a/file1; date >> b/file2; mtree < /tmp/manifest.txt || echo fail
.:      modification time (Wed Mar 28 10:34:56 2018, Wed Mar 28 10:39:39 2018)
c:      modification time (Wed Mar 28 10:25:42 2018, Wed Mar 28 10:41:59 2018)
extra: c/FILE3
b/file2:
        size (29, 58)
        modification time (Wed Mar 28 10:25:37 2018, Wed Mar 28 10:47:31 2018)
        sha256digest (0x9f7a0a49475bb6f98e609a4e057f0bc702c5e4706be5bd656a676fd8d15da7ef, 0x569c17bd1a1ca2447fd8167f103531bf3a7b7b4268f0f68b18506e586e7eea94)
a:      modification time (Wed Mar 28 10:25:32 2018, Wed Mar 28 10:41:59 2018)
./a/file1 missing
./c/file3 missing
fail

答案2

md5sum -c manifest.txt尊重儲存在 中的路徑manifest.txt。該find程式會取代{}找到的文件的完整路徑,包括在find命令列中指定的任何搜尋位置,即對於文件,./a/b/c/d/e它將替換相同的./a/b/c/d/e命令 find ./a -type f -exec md5sum {} \;

可能的問題是絕對路徑,因此更合適的“清單建立命令”是:

cd /mnt/my-volume; find  -type f -exec md5sum {} + > manifest.txt

sed但是,您始終可以修復mainfest.txt 內的路徑

相關內容