Existem dezenas de utilitários de linha de comando padrão que podem ser pendurados em um descritor e aguardar a entrada. Isso é muito bonito como todos eles funcionam. dd é o único que pode mostrar como um descritor é agora .
Pessoalmente, eu realmente não entendo a utilidade por trás da opção iflag=fullblock do GNU. Quero dizer, você pode apenas cat da sua entrada pelo menos com a mesma facilidade e sem precisar se preocupar com o tamanho dos blocos de E / S.
Mas dd pode pegar uma parte de um fluxo - e isso pode ser feito em read() / write() limites em um sistema razoavelmente moderno.
{ ( sleep 1 #don't write() til dd is definitely setup
printf 123 #write() 3 bytes
printf %-30s\n 456 #write() 31 bytes
printf you\ there\? #write() 10 bytes
)| dd bs=64 count=2 conv=sync| #2 64 byte read()/write() 0000000 1 2 3 dd: warning: partial read (3 bytes); suggest iflag=fullblock
0+2 records in
2+0 records out
128 bytes (128 B) copied, 1.00161 s, 0.1 kB/s
{ ( sleep 1 #don't write() til dd is definitely setup
printf 123 #write() 3 bytes
printf %-30s\n 456 #write() 31 bytes
printf you\ there\? #write() 10 bytes
)| dd bs=64 count=2 conv=sync| #2 64 byte read()/write() 0000000 1 2 3 dd: warning: partial read (3 bytes); suggest iflag=fullblock
0+2 records in
2+0 records out
128 bytes (128 B) copied, 1.00161 s, 0.1 kB/s
%pre% %pre% %pre% %pre% %pre% %pre% %pre% %pre% %pre% %pre% %pre% %pre%
0000020 %pre% %pre% %pre% %pre% %pre% %pre% %pre% %pre% %pre% %pre% %pre% %pre% %pre% %pre% %pre% %pre%
0000040 %pre% %pre% %pre% %pre% %pre% %pre% %pre% %pre% %pre% %pre% %pre% %pre% %pre% %pre% %pre% %pre%
0000060 %pre% %pre% %pre% %pre% %pre% %pre% %pre% %pre% %pre% %pre% %pre% %pre% %pre% %pre% %pre% %pre%
0000100 4 5 6
0000120 \n %pre%
0000140 %pre% %pre% %pre% %pre% %pre% %pre% %pre% %pre% %pre% %pre% %pre% %pre% %pre% %pre% %pre% %pre%
0000160 %pre% %pre% %pre% %pre% %pre% %pre% %pre% %pre% %pre% %pre% %pre% %pre% %pre% %pre% %pre% %pre%
0000200
-padded blocks
od -vtc #show it with octal radices
} 2>/dev/null #drop stderr
%pre% %pre% %pre% %pre% %pre% %pre% %pre% %pre% %pre% %pre% %pre%
0000020 %pre% %pre% %pre% %pre% %pre% %pre% %pre% %pre% %pre% %pre% %pre% %pre% %pre% %pre% %pre% %pre%
0000040 %pre% %pre% %pre% %pre% %pre% %pre% %pre% %pre% %pre% %pre% %pre% %pre% %pre% %pre% %pre% %pre%
0000060 %pre% %pre% %pre% %pre% %pre% %pre% %pre% %pre% %pre% %pre% %pre% %pre% %pre% %pre% %pre% %pre%
0000100 4 5 6
0000120 \n %pre%
0000140 %pre% %pre% %pre% %pre% %pre% %pre% %pre% %pre% %pre% %pre% %pre% %pre% %pre% %pre% %pre% %pre%
0000160 %pre% %pre% %pre% %pre% %pre% %pre% %pre% %pre% %pre% %pre% %pre% %pre% %pre% %pre% %pre% %pre%
0000200
-padded blocks
od -vtc #show it with octal radices
} 2>/dev/null #drop stderr
%pre%
dd faz um único read() por bloco de entrada. Se o arquivo que ele tenta read() não tiver tantos dados quanto ele solicitou, não importa - o um read() conta como um bloco de entrada . É assim que funciona - isto é, a utilidade primária de dd .
Quando tiver feito seu trabalho, dd relatará todos os blocos de entrada / saída com os quais lidou. Executando o comando acima novamente, mas descartando stdout desta vez ...
%pre%
Cada vez que dd fez read(0,&in,64) read voltou curto - porque seu descritor de arquivo stdin não tinha bytes suficientes esperando que ele cumprisse sua solicitação quando o fez. E assim dd read() 0 registros de entrada completos e dois curtos. É o que esses relatórios significam.