Dd
您如何對 dd 進行精細控制?
我有一張 64GB 的 MicroSD 卡。我用這個寫了一個大小為 16GB 的圖像:
$ sudo dd if=my_image.img of=/dev/sdb bs=4M 3798+1 records in 3798+1 records out 15931539456 bytes (16 GB, 15 GiB) copied, 657.848 s, 24.2 MB/s
現在,我想用 dd 拍攝同一張 64GB SD 卡的前 15931539456 字節 (16GB) 的圖像,最終得到一個與我開始使用的圖像具有相同校驗和的圖像。
據我了解,上述 dd 的結果 (3798+1) 顯示源圖像有 3798 次完整讀取和 1 次部分讀取,因為源圖像的大小沒有均勻地分成 4M 塊。那麼我如何告訴 dd 現在將 15931539456 字節從 SD 卡複製到一個新文件中,一次 4M?
我假設我可以做類似的事情:
sudo dd if=/dev/sdb of=new_image.img bs=1 count=15931539456
但是有一個那麼小的緩衝區會使操作永遠持續下去。有沒有辦法告訴它使用 4M 的緩衝區,但只複製 X 個字節,即使最後會導致短讀取?
幾種可能:
- 使用較小
bs
但不是很小的 :dd if=/dev/sdb of=new_image.img bs=512k count=30387
這不是一個通用的解決方案。它在這裡有效,因為
15931539456
可以分解。 2. 使用您想要的bs
,閱讀更多內容並即時截斷:dd if=/dev/sdb bs=4M | head -c 15931539456 >new_image.img
你不需要
count=3799
這裡。好吧,你甚至不需要dd
:head -c 15931539456 /dev/sdb >new_image.img
我希望
head
閱讀理智的塊並表現良好。head -c
POSIX 不需要註釋。 3. 使用您想要的bs
,閱讀更多內容並稍後截斷:dd if=/dev/sdb of=new_image.img bs=4M count=3799 truncate -s 15931539456 new_image.img
truncate
雖然不是攜帶式的。 4. 用你想要的bs
,少讀;然後閱讀其餘部分bs=1
:dd if=/dev/sdb of=new_image.img bs=4M count=3798 offset=$((3798*4*1024*1024)) remaining=$((15931539456-offset)) dd if=/dev/sdb of=new_image.img bs=1 skip="$offset" seek="$offset" count="$remaining"
注意通常
dd
可能會讀取部分塊,這仍然會增加計數(比較這個答案)。雖然從塊設備讀取這可能不會發生,但一般的解決方案仍然是iflag=fullblock
在您依賴時始終指定count
並且bs
大於1
. 不幸fullblock
的是,POSIX 不需要,因此您dd
可能不支持它。