Resumo: ddé uma ferramenta irritante que é difícil de usar corretamente. Não o use, apesar dos inúmeros tutoriais que lhe dizem isso. ddtem uma vibração de "unix street cred", mas se você realmente entende o que está fazendo, saberá que não deve tocá-lo com uma vara de três metros.
ddfaz uma única chamada para a chamada do readsistema por bloco (definida pelo valor de bs). Não há garantia de que a readchamada do sistema retorne tantos dados quanto o tamanho do buffer especificado. Isso costuma funcionar para arquivos regulares e dispositivos de bloco, mas não para pipes e alguns dispositivos de caracteres. Consulte Quando o dd é adequado para copiar dados? (ou, quando são lidos () e gravados () parciais) para obter mais informações. Se a readchamada do sistema retornar menos de um bloco completo, ddtransferirá um bloco parcial. Ele ainda copia o número especificado de blocos, portanto, a quantidade total de bytes transferidos é menor que o solicitado.
O aviso sobre uma "leitura parcial" diz exatamente isso: uma das leituras foi parcial, portanto ddtransferiu um bloco incompleto. Na contagem de blocos, +1significa que um bloco foi lido parcialmente; como a contagem de saída é +0, todos os blocos foram gravados como lidos.
Isso não afeta a aleatoriedade dos dados: todos os bytes ddgravados são bytes dos quais eles são lidos /dev/urandom. Mas você tem menos bytes do que o esperado.
O Linux /dev/urandomacomoda solicitações grandes e arbitrárias (fonte: extract_entropy_userin drivers/char/random.c), portanto ddnormalmente é seguro ao ler a partir dele. No entanto, a leitura de grandes quantidades de dados leva tempo. Se o processo receber um sinal, a readchamada do sistema retornará antes de preencher seu buffer de saída. Esse é um comportamento normal, e os aplicativos devem chamar readem um loop; ddnão faz isso, por razões históricas ( ddas origens são obscuras, mas parece ter começado como uma ferramenta para acessar fitas, que têm requisitos peculiares e nunca foi adaptada para ser uma ferramenta de uso geral). Quando você verifica o progresso, isso envia ao ddprocesso um sinal que interrompe a leitura. Você pode escolher entre saber quantos bytesddserá copiado no total (lembre-se de não interrompê-lo - sem verificação de progresso, sem suspensão) ou sabendo quantos bytes ddforam copiados até agora; nesse caso, você não pode saber quantos bytes serão copiados.
A versão do ddGNU coreutils (como encontrada no Linux não incorporado e no Cygwin) possui uma flag fullblockque diz ddpara chamar readum loop (e o mesmo para write) e, portanto, sempre transfere blocos completos. A mensagem de erro sugere que você o use; você deve sempre usá-lo (nos sinalizadores de entrada e de saída), exceto em circunstâncias muito especiais (principalmente ao acessar fitas) - se você usar dd, ou seja: geralmente existem soluções melhores (veja abaixo).
dd if=/dev/urandom iflag=fullblock oflag=fullblock of=file bs=1M count=1000000
Outra maneira possível de ter certeza do que ddfará é passar o tamanho de um bloco de 1. Então, você pode dizer quantos bytes foram copiados da contagem de blocos, embora não tenha certeza do que acontecerá se um readfor interrompido antes de ler o primeiro byte (o que não é muito provável na prática, mas pode acontecer). No entanto, mesmo que funcione, isso é muito lento.
O conselho geral sobre o uso ddé não usardd . Embora ddseja frequentemente anunciado como um comando de baixo nível para acessar dispositivos, na verdade não existe: toda a mágica acontece na parte do arquivo do dispositivo /dev/…, ddé apenas uma ferramenta comum com um alto potencial de uso indevido, resultando em perda de dados . Na maioria dos casos, existe uma maneira mais simples e segura de fazer o que você deseja, pelo menos no Linux.
Por exemplo, para ler um certo número de bytes no início de um arquivo, basta chamar head:
head -c 1000000m </dev/urandom >file
Fiz uma referência rápida na minha máquina e não observei nenhuma diferença de desempenho entre ddum tamanho de bloco grande e head.
Se você precisar pular alguns bytes no início, entre tailem head:
dd if=input of=output count=C bs=B seek=S
<input tail -c +$((S*B+1)) | head -c $((C*B)) >output
Se você quiser ver o progresso, ligue lsofpara ver o deslocamento do arquivo. Isso funciona apenas em um arquivo regular (o arquivo de saída no seu exemplo), não em um dispositivo de caractere.
lsof -a -p 1234 -d 1
cat /proc/1234/fdinfo/1
Você pode ligar pvpara obter um relatório de progresso (melhor que ddo), às custas de um item adicional no pipeline (em termos de desempenho, é quase imperceptível).