从规格:
- 如果
bs=
expr
指定了操作数,并且不要求除sync
,noerror
或以外的任何转换notrunc
,则将从每个输入块返回的数据写为一个单独的输出块;如果read()
返回的结果小于完整的块,并且sync
未指定转换,则结果输出块的大小应与输入块的大小相同。
所以这可能是引起您困惑的原因。是的,因为dd
是专为阻塞而设计的,所以默认情况下read()
会将partial s 1:1映射到partial write()
s,否则sync
在尾部填充NUL或空格字符d bs=
时conv=sync
将其指定为size 。
这意味着在任何情况下都dd
可以安全地用于复制数据(不存在由于部分读取或写入而导致损坏的风险),但是在任何情况下它都受到count=
参数的任意限制,否则dd
将很高兴write()
以相同大小的块输出数据直到那些输入完全通过它的人read()
为止read()
。即使这需要注意的是唯一真正在bs=
指定或者obs=
是不指定,在规范的状态非常下一句:
- 如果
bs=
expr
未指定操作数,或未请求,或进行转换sync
,则应处理输入并将其收集到完整尺寸的输出块中,直到到达输入结尾为止。noerror
notrunc
没有ibs=
和/或obs=
参数就没有关系-因为ibs
和obs
缺省情况下都是相同的大小。但是,您可以通过为两者指定不同的大小而不指定bs=
(因为它具有优先级)来明确了解输入缓冲。
例如,如果您这样做:
IN| dd ibs=1| OUT
...然后,通过dd
将每个单个字节收集到单个输出块中,POSIX 将以write()
512 字节为块。read()
否则,如果您这样做...
IN| dd obs=1kx1k| OUT
......一个POSIX dd
会read()
以最大的一次是512个字节,但write()
每兆字节大小的输出块(内核允许和可能除外最后-因为这是EOF)通过收集输入到全全尺寸输出块。
同样来自规范:
count=
映射到i?bs=
块,因此为了处理count=
可移植的任意限制,您需要两个dd
s。使用2 dd
s 的最实用方法是将一个输出与另一个输入进行管道传输,这无疑使我们处于读写特殊文件的境界,而与原始输入类型无关。
IPC管道意味着[io]bs=
,为了安全地指定args,必须将这些值保持在系统定义的PIPE_BUF
限制内。POSIX指出,系统内核只能保证原子read()
S和write()
限度内小号PIPE_BUF
中定义limits.h
。POSIX保证PIPE_BUF
是至少 ...
... (这也是默认的dd
I / O块大小),但实际值通常至少为4k。在最新的linux系统上,默认值为64k。
因此,在设置dd
流程时,您应该基于以下三个值在阻塞因素上执行此操作:
- bs =(obs =
PIPE_BUF
或更小)
- n =读取的所需总字节数
- 计数= n / bs
喜欢:
yes | dd obs=1k | dd bs=1k count=10k of=/dev/null
10240+0 records in
10240+0 records out
10485760 bytes (10 MB) copied, 0.1143 s, 91.7 MB/s
您必须同步i / ow / dd
才能处理不可搜索的输入。换句话说,使管道缓冲区显式,它们不再是问题。那dd
是为了什么 这里的未知数量是yes
的缓冲区大小-但是如果您将其限制为另一个已知数量,dd
则在不知情的情况下乘法可以dd
安全地用于复制数据(不存在由于部分读取或写入而导致损坏的风险)即使count=
在任何POSIX系统上任意限制输入w / w /任意输入类型并且不丢失单个字节的情况下,也是如此。
这是POSIX规范的摘录:
ibs=
expr
- 指定输入块的大小(以字节为单位)(默认值为512)。
expr
obs=
expr
- 指定输出块的大小(以字节为单位)(默认值为512)。
expr
bs=
expr
- 将输入和输出块大小均设置为
expr
字节,ibs=
并替换为和obs=
。如果没有转换以外sync
,noerror
和notrunc
被指定时,每一个输入块应被复制到输出为单个块,而不聚集短块。
您还将在这里找到一些更好的解释。