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.