從一個硬碟複製到另一個硬碟後驗證大目錄

從一個硬碟複製到另一個硬碟後驗證大目錄

我有一個使用 Ubuntu 的家庭文件伺服器。

最近,我的一個驅動器已滿,所以我又買了一個並把它扔在那裡。

我有一個非常大的資料夾,目錄大小約為1.7T,包含相當數量的檔案。

我用了GCP將檔案從舊驅動器複製到新驅動器,似乎工作正常。

我現在想根據舊磁碟機上的原始目錄驗證新磁碟機上的新目錄,然後再從舊磁碟機中刪除資料以釋放空間。我知道我可以透過 CRC 檢查來做到這一點。

具體來說,我可以如何做到這一點?

答案1

我只需使用diff命令:

diff -rq --no-dereference /path/to/old/drive/ /path/to/new/drive/

這會讀取並比較目錄樹中的每個檔案並報告任何差異。該-r標誌以遞歸方式比較目錄,而該-q標誌只是在文件不同時將訊息打印到屏幕上,而不是打印實際差異(就像對文本文件那樣)。--no-dereference如果存在不同的符號鏈接,例如在一個目錄中存在符號鏈接,而在其對應的目錄中存在鏈接到的文件的副本,則該標誌可能很有用。

如果diff命令列印無輸出,這意味著目錄樹確實是相同的;可以運行echo $?驗證其退出狀態為0,說明兩組文件是相同的。

我不認為計算 CRC 或校驗和在這種情況下特別有用。如果兩組文件位於不同的系統上,並且每個系統都可以計算自己的文件組的校驗和,因此只需要透過網路發送校驗和,則更有意義。計算校驗和的另一個常見原因是保留校驗和的副本以供將來使用。

答案2

同步通常用於複製文件而不是gcp,但它也可用於驗證副本,無論副本是如何製作的。簡單地做

rsync -niaHc /origfolder/ /copyfolder

請小心以/.選項有

  • -n請勿複製(不做任何更改)
  • -i逐項列出差異
  • -a保留(即比較,因為我們有-n)權限、所有權、符號連結等並遞歸目錄
  • -H保留硬連結
  • -c比較校驗和

輸出顯示一個程式碼,詳細說明每個不同檔案或目錄的差異。如果它們相同則沒有輸出。該程式碼具有一些列YXcstpoguax,其中每個字元是一個點(.如果比較的方面沒問題),或者是一個字母:

Y is type of update: 
   < sent (not appropriate in this case)
   > need to copy 
   c missing file or directory
   h is hard link
   . no update
   * and rest of line is a message, eg *deleting
X file type: f file  d dir  L symlink  D device S special file
c checksum differs. + new item  " " same
s size differs
t timestamp differs
p permissions differ
o owner differ
g group differ
u (not used)
a acl differ
x extended attributes differ

例如,

.d..t...... a/b/                    directory timestamp differs
cL+++++++++ a/b/d -> /nosuch2       symbolic link missing
cS+++++++++ a/b/f                   special file missing (a/b/f is a fifo)
>f..t...... a/b/ff                  file timestamp differs
hf          a/b/xx1 => a/b/xx       files should be a hard linked
cLc.t...... a/b/z -> /tmp/hi2       symbolic link to different name
cd+++++++++ a/c/                    directory missing
>f+++++++++ a/c/i.10                missing file needs to be copied

請參閱man rsync下文--itemize-changes以了解更多詳細資訊。如果第三列c或第四列有差異s,則表示資料已嚴重損壞。其他標誌(例如不同的權限、所有者或時間戳記)對您來說可能不太重要。如果所有檔案都被標記為“遺失”,那麼您可能沒有提供正確的目錄進行比較。如果您確定,執行不含該-n標誌的 rsync 將「修復」差異。

答案3

我有同樣的問題,我用過安東尼的回答,有一點扭曲。

如果發生某些硬體故障(例如輸入/輸出錯誤),導致 diff 退出,直接應用他的答案將會失敗。

我整理了他的答案,以及這個答案,並將其全部放入:

find /path/to/original -type f -exec bash -c 'diff -rq --no-dereference "$@" "/path/to/destination/$(sed -r "s/^.*(<first-common-ancestor>.*)$/\1/g" <<<"$@")"' bash {} \;
  • 替換/path/to/original為您複製的原始目錄的路徑。
  • 替換/path/to/destination為您複製到的目標目錄的路徑。
  • 替換<first-common-ancestor>為兩者之間的共同祖先目錄。範例:您正在從 複製/media/foo/bar/media/test/dst/,因此dst,在複製操作完成後, 具有目錄bar。第一個共同祖先就bar在這裡;因為下面的所有文件bar都將具有相同的相對路徑。

一些注意事項:

  • bash -c和部分bash {}用於對檔案名稱進行安全替換;為了安全起見,不要受到可能的攻擊(例如特權提升)的傷害。
  • sed部分是刪除找到的檔案的絕對路徑並僅使用相對路徑(這與 using 不同execdir)。如果您不確定這有什麼用,請嘗試將其刪除並檢查錯誤訊息:)
  • <<<變數作為字串讀取,而不是將其作為要讀取的檔案的路徑讀取。

相關內容