男人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=' 指定的大小)。