
我在恢復 ddrescue 時使用了錯誤的輸出檔名,犯了一個愚蠢的錯誤。這就是發生的事情:
ddrescue -b 2048 -d -v /dev/sr1 IDTa.img IDTa.ddrescue.log
然後計算機崩潰了,我錯誤地恢復了:
ddrescue -b 2048 -d -v /dev/sr1 IDTa.iso IDTa.ddrescue.log
我收集到兩個圖像檔案都會開始全部歸零,所以我想如果我對兩個檔案進行布林或運算,那麼結果將是如果我沒有犯錯的話 ddrescue 會輸出什麼?
這些文件不是彼此的延續(例如如何合併兩個 ddrescue 影像?)因為我之前已經運行過ddrescue -n
,並且成功完成。即 IDTa.img 包含大部分數據,IDTa.iso 包含圖像各處的分散塊(這些塊在 IDTa.img 中為零)。
有沒有簡單的 CLI 方法可以做到這一點?我可能可以用 C 語言做到這一點,但我很生疏!也可能是 Python 的一個很好的第一個練習,我從來沒有時間學習它!儘管如此,如果已經存在一些東西,就不要特別想重新發明輪子。不太注重性能。
更新:(如果這是回复答案的錯誤位置,我深表歉意。“評論”選項似乎允許的字符太少,所以我在這裡回复!)
我還嘗試過使用 '--fill-mode=?' 進行 ddrescue作為上述問題的解決方案,但沒有成功。這就是我所做的:
ddrescue --generate-mode -b 2048 -v /dev/sr1 IDTa.img IDTa.img.log
cp IDTa.img IDTa.img.backup
ddrescue '--fill-mode=?' -b 2048 -v IDTa.iso IDTa.img IDTa.img.log
為了檢查,我查找了 IDTa.iso 有資料的第一個位置:
hexdump -C IDTa.iso |less
輸出是:
00000000 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
*
001da800 00 00 01 ba 21 00 79 f3 09 80 10 69 00 00 01 e0 |....!.y....i....|
...
001db000 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
*
...
我在 IDTa.img 中查找了 001da800:
hexdump -C IDTa.img |less
/001da800
輸出:
001da800 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
*
001db000 00 00 01 ba 21 00 7b 00 bf 80 10 69 00 00 01 e0 |....!.{....i....|
...
那麼,位置 001da800 處的資料還沒有從檔案 IDTa.iso 複製到 IDTa.img 嗎?
檢查IDTa.img.log:
# Mapfile. Created by GNU ddrescue version 1.22
# Command line: ddrescue --fill-mode=? -b 2048 -v IDTa.iso IDTa.img IDTa.img.log
# Start time: 2021-06-28 13:52:39
# Current time: 2021-06-28 13:52:46
# Finished
# current_pos current_status current_pass
0x299F2000 + 1
# pos size status
0x00000000 0x00008000 ?
0x00008000 0x001D2800 +
0x001DA800 0x00000800 ?
0x001DB000 0x00049000 +
...
以及現實檢驗:
diff -q IDTa.img IDTa.img.backup
返回沒有區別。
更新2:
@Kamil 透過刪除參數編輯了解決方案(見下文)--fill-mode=?
。看來工作了!
答案1
我認為這可以自己完成ddrescue
。你需要--generate-mode
。
當
ddrescue
使用選項呼叫時--generate-mode
,它在“生成模式”下運行,這與預設的“救援模式”不同。也就是說,在「生成模式」下ddrescue
不會拯救任何東西。它只是嘗試產生mapfile
以供以後使用。[…]
ddrescue
在某些情況下可以從 和 產生近似mapfile
,infile
和 中的(部分)副本outfile
,這幾乎與精確的 一樣好mapfile
。它透過簡單地假設包含全零的扇區沒有被拯救來實現這一點。[…]
ddrescue --generate-mode infile outfile mapfile
(來源)
複製這兩個影像,以防萬一。如果您的檔案系統支援 CoW-copy,則使用cp --reflink=always
每個影像幾乎可以立即進行複製。
您需要確保兩個圖像的大小相同。如果其中之一較小,則應將其放大,即應附加零(可能是稀疏零)。此程式碼將自動執行此操作(truncate
必需):
( f1=IDTa.img
f2=IDTa.iso
s1="$(wc -c <"$f1")"
s2="$(wc -c <"$f2")"
if [ "$s2" -gt "$s1" ]; then
truncate -s "$s2" "$f1"
else
truncate -s "$s1" "$f2"
fi
)
(我使用了子 shell,因此變數會隨之消失,而主 shell 不受影響。)
現在讓工具分析您的第一張影像並找出哪些磁區可能未獲救:
ddrescue --generate-mode -b 2048 -v /dev/sr1 IDTa.img new_mapfile
注意new_mapfile
這裡有一個新文件,不是你的IDTa.ddrescue.log
。請勿觸摸IDTa.ddrescue.log
。
new_mapfile
產生後,其中的行應顯示狀態+
或?
,取決於對應的片段是否被視為「已救援」或「未嘗試」。
IDTa.img
現在您想要用來自 的資料填充據稱「未嘗試過」的區塊IDTa.iso
。下一個命令將修改IDTa.img
.
IDTa.img
透過讀取資料來拯救所謂的「未嘗試過」的區塊IDTa.iso
:
ddrescue -b 2048 -v IDTa.iso IDTa.img new_mapfile
現在,修改後的內容IDTa.img
和未修改的內容IDTa.ddrescue.log
應該和您沒有犯錯一樣好。
筆記:
- 可能發生了一些包含全零的扇區實際上被拯救的情況。
--generate-mode
將它們分類為?
.它們將充滿從IDTa.iso
「徒勞」中獲取的數據。這對於最終結果並不重要,因為它們在另一個文件中也全為零。 IDTa.iso
如果在整個過程中互換和 ,結果應該是相同的IDTa.img
(但請記住,如果這樣做,結果將在 中IDTa.iso
)。所以有一個選擇。我--generate-mode
將使用預計包含全零的扇區較少的文件,因為這應該最大限度地減少最後一個命令的工作量。- 此方法適用於常規文件
IDTa.iso
和IDTa.img
.相反,如果您有一個區塊設備,那麼您工作之前的「隨機」內容ddrescue
會幹擾並破壞結果(因此,首先解決不同大小的潛在問題是沒有意義的,這truncate
沒有幫助)。 - 我在嘗試拯救一個人時複製了你的錯誤後測試了該程序片狀裝置。