男人dd
:
dd - 轉換並複製文件
我傾向於使用dd
.奇怪的是,複製 1 位元組文字檔案後變得小得多:
$ block_size=1; device_to_edit=/media/ramdrive/a; device_from=/media/ramdrive/b; echo "aaaaaaaaaa">$device_to_edit; echo "bbbbbbbbbb">$device_from; cat $device_to_edit; cat $device_from; dd if=$device_from of=$device_to_edit count=1 seek=2 skip=2 bs=$block_size; cat $device_to_edit
aaaaaaaaaa
bbbbbbbbbb
1+0 records in
1+0 records out
1 byte copied, 0,000156688 s, 6,4 kB/s
aab
它說1 byte copied
,為什麼文件結尾消失了?
添加:
正如評論所建議的,conv=notrunc
修復它。但來自man
:
conv=CONVS 根據逗號分隔的符號清單轉換文件
我不想轉換文件。在閱讀有關複製區塊設備的內容時,我沒有看到這個操作數。當不是所有檔案(例如 /dev/sdb 中的一個 512 位元組區塊:USB 磁碟)都更改時,是否總是需要它?
答案1
你正在做的是這樣的:
block_size=1;
dd ... count=1 seek=2 skip=2 bs=$block_size;
你要求dd
只複製一個位元組。但是,預設情況下,它會截斷輸出文件,以便在文件結尾處dd
完成。
$ echo abcdefgh > test1
$ echo 12345678 > test2
$ dd count=1 bs=1 skip=2 seek=2 if=test1 of=test2
1+0 records in
1+0 records out
1 byte copied, 0.000179375 s, 5.6 kB/s
$ cat test2; echo
12c
我的 GNU 線上說明頁面似乎沒有明確說明這一點,但是POSIX 描述確實:
of=file
指定輸出路徑名; [...] 如果seek=expr
指定了,但conv=notrunc
沒有指定,則複製的效果應是保留 dd 尋找的輸出檔案中的區塊,但不應保留輸出檔案的其他部分。 (如果查找的大小加上輸入檔案的大小小於輸出檔案的先前大小,則輸出檔案應透過副本縮短。[...])
為了防止這種情況,請新增conv=notrunc
選項:
notrunc
不要截斷輸出文件
$ echo 12345678 > test2
$ dd conv=notrunc count=1 bs=1 skip=2 seek=2 if=test1 of=test2
1+0 records in
1+0 records out
1 byte copied, 0.00019385 s, 5.2 kB/s
$ cat test2
12c45678
notrunc
不會使其修改實際複製的數據,因此從這個意義上說,它不是“轉換”,即使它被視為conv
.
請注意,如果count=
給出,dd
則執行多次read()
調用,這意味著如果您從可以提供短讀取的設備讀取數據,則實際讀取的數據量不是count
倍bs
。
答案2
應該查看完整的文檔man dd
:
Full documentation at: <https://www.gnu.org/software/coreutils/dd>
or available locally via: info '(coreutils) dd invocation'
'of=FILE' 寫入 FILE 而不是標準輸出。除非給出 'conv=notrunc',否則 'dd' 會將 FILE 截斷為零位元組(或用 'seek=' 指定的大小)。