Você está observando uma combinação do comportamento peculiar de dd com o comportamento peculiar do /dev/random do Linux. Ambos, a propósito, raramente são a ferramenta certa para o trabalho.
O /dev/random do Linux retorna dados com moderação. Baseia-se no pressuposto de que a entropia no gerador de números pseudo-aleatórios se extingue a uma taxa muito rápida. Como a coleta de nova entropia é lenta, /dev/random geralmente desiste apenas alguns bytes de cada vez.
dd é um programa antigo e mal-humorado inicialmente destinado a operar em dispositivos de fita. Quando você diz para ler um bloco de 1kB, ele tenta ler um bloco. Se a leitura retornar menos de 1024 bytes, difícil, é tudo que você recebe. Portanto, dd if=/dev/random bs=1K count=2 faz duas chamadas read(2) . Como ele está lendo /dev/random , as duas chamadas read normalmente retornam apenas alguns bytes, em número variável, dependendo da entropia disponível. Veja também Quando o dd é adequado para copiar dados? (ou, quando são lidos () e escritos () parciais)
A menos que esteja projetando um instalador ou clonador de sistema operacional, você nunca deve usar /dev/random no Linux, sempre /dev/urandom . A página urandom man é um tanto enganadora; /dev/urandom é de fato adequado para criptografia, até mesmo para gerar chaves de longa duração. A única restrição com /dev/urandom é que ela deve ser fornecida com entropia suficiente; As distribuições Linux normalmente salvam a entropia entre as reinicializações, portanto, a única vez em que você pode não ter entropia suficiente é em uma instalação nova. A entropia não se desgasta em termos práticos. Para obter mais informações, leia É um rand de / dev / urandom secure para uma chave de login? e Feeding / dev / pool de entropia aleatória? .
A maioria dos usos de dd é melhor expressa com ferramentas como head ou tail . Se você quiser 2kB de bytes aleatórios, execute
head -c 2k </dev/urandom >rand
Com kernels mais antigos do Linux, você pode se safar com
dd if=/dev/urandom of=rand bs=1k count=2
porque /dev/urandom felizmente retornou quantos bytes foram solicitados. Mas isso não é mais verdade desde o kernel 3.16, está agora limitado a 32MB .
Em geral, quando você precisa usar dd para extrair um número fixo de bytes e sua entrada não vem de um arquivo ou dispositivo de bloco comum, você precisa ler byte por byte: dd bs=1 count=2048 .