从规格:
- 如果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,则应处理输入并将其收集到完整尺寸的输出块中,直到到达输入结尾为止。noerrornotrunc
没有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=可移植的任意限制,您需要两个dds。使用2 dds 的最实用方法是将一个输出与另一个输入进行管道传输,这无疑使我们处于读写特殊文件的境界,而与原始输入类型无关。
IPC管道意味着[io]bs=,为了安全地指定args,必须将这些值保持在系统定义的PIPE_BUF限制内。POSIX指出,系统内核只能保证原子read()S和write()限度内小号PIPE_BUF中定义limits.h。POSIX保证PIPE_BUF是至少 ...
... (这也是默认的ddI / 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被指定时,每一个输入块应被复制到输出为单个块,而不聚集短块。
 
您还将在这里找到一些更好的解释。