É porque você está fazendo errado.
Você está usando bs=1M
, mas a leitura de stdin, pipe, terá leituras menores. De fato, de acordo com o dd, você não conseguiu uma única leitura completa.
E então você tem conv=sync
, que complementa as leituras incompletas com zeros.
0+15281 records in
15280+0 records out
dd
recebeu 0 completo e 15281 leituras incompletas e escreveu 15280 blocos completos (conv = sync zero filled). Então a saída é muito maior que a entrada, até você não ter mais espaço.
sync pad every input block with NULs to ibs-size; when used with
block or unblock, pad with spaces rather than NULs
Para resolver isso, você pode remover conv=sync
e adicionar iflag=fullblock
.
Para ilustrar, considere yes
, que por padrão envia infinito "y \ ny \ ny \ n".
$ yes
y
y
y
^C
$ yes | hexdump -C
00000000 79 0a 79 0a 79 0a 79 0a 79 0a 79 0a 79 0a 79 0a |y.y.y.y.y.y.y.y.|
*
Com dd bs=1M conv=sync
, é assim:
$ yes | dd bs=1M conv=sync | hexdump -C
00000000 79 0a 79 0a 79 0a 79 0a 79 0a 79 0a 79 0a 79 0a |y.y.y.y.y.y.y.y.|
*
0001e000 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
*
00100000 79 0a 79 0a 79 0a 79 0a 79 0a 79 0a 79 0a 79 0a |y.y.y.y.y.y.y.y.|
*
00112000 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
*
Portanto, ele obtém um bloco incompleto de "y \ ny \ ny \ n" (0x00000 - 0x1e000, 122880 Bytes) e grava o 1M restante como zeros (0x01e000 - 0x100000, 925696 Bytes). Na maioria dos casos, você não quer que isso aconteça. O resultado é aleatório, assim como você não tem controle real sobre quão incompleta cada leitura se tornaria. Como aqui a segunda leitura não é mais 122880 bytes, mas 73728 bytes.
dd conv=sync
raramente é útil e, mesmo nos casos em que seria bem-vindo, como escrever zeros quando você receber erros de leitura, as coisas serão vai terrivelmente errado com isso.