Como eu queria produzir um arquivo aleatório de 1 GB, usei o seguinte comando.
dd if=/dev/urandom of=output bs=1G count=1
Mas, em vez disso, sempre que inicio este comando, recebo um arquivo de 32 MB:
<11:58:40>$ dd if=/dev/urandom of=output bs=1G count=1
0+1 records in
0+1 records out
33554431 bytes (34 MB, 32 MiB) copied, 0,288321 s, 116 MB/s
O que está errado?
EDITAR:
Graças a ótimas respostas neste tópico, eu vim com uma solução com 32 pedaços de 32 MB de tamanho, o que perfaz 1 GB:
dd if=/dev/urandom of=output bs=32M count=32
Outra solução foi fornecida: lê 1 GB diretamente na memória e depois grava no disco. Esta solução consome muita memória, portanto não é preferida:
dd if=/dev/urandom of=output bs=1G count=1 iflag=fullblock
script
dd
random-number-generator
Trismegistos
fonte
fonte
dd
. Eu usariahead
,cat
oursync
em seu lugar quase sempre. E sua pergunta se uma das razões pelas quais as alternativas são geralmente mais seguras.head
não pode executar esta tarefa sem a-c
opção que não está no POSIX . Não conheço nenhuma versãocat
que possa resolver isso.rsync
é um utilitário completamente fora do padrão. Isso não está aqui nem ali; folheando sua página de manual, também não vejo como ele pode resolver esse problema./dev/urandom
não está na POSIX ou ...Respostas:
bs
, o tamanho do buffer, significa o tamanho de uma única chamada read () feita por dd.(Por exemplo, ambos
bs=1M count=1
ebs=1k count=1k
resultará em um arquivo 1 MiB, mas a primeira versão o fará em uma única etapa, enquanto a segunda fará em 1024 pequenos pedaços.)Os arquivos regulares podem ser lidos em praticamente qualquer tamanho de buffer (desde que esse buffer caiba na RAM), mas os dispositivos e arquivos "virtuais" geralmente trabalham muito perto das chamadas individuais e têm alguma restrição arbitrária da quantidade de dados que eles produzirão por chamada read ().
Para
/dev/urandom
, este limite é definido em urandom_read () em drivers / char / random.c :Isso significa que toda vez que a função for chamada, ela limitará o tamanho solicitado a 33554431 bytes.
Por padrão, diferentemente da maioria das outras ferramentas, o dd não tentará novamente depois de receber menos dados do que o solicitado - você obtém o 32 MiB e é isso. (Para fazê-lo tentar novamente automaticamente, como na resposta de Kamil, você precisará especificar
iflag=fullblock
.)Observe também que "o tamanho de uma única leitura ()" significa que todo o buffer deve caber na memória de uma só vez; portanto, tamanhos enormes de blocos também correspondem ao uso massivo de memória por dd .
E é tudo inútil, porque você geralmente não obtém desempenho acima de 16 a 32 blocos MiB - os syscalls não são a parte mais lenta aqui, o gerador de números aleatórios é.
Portanto, para simplificar, basta usar
head -c 1G /dev/urandom > output
.fonte
iflag=fullblock
é uma extensão GNU dodd
utilitário POSIX . Como a pergunta não especifica o Linux, acho que o uso de extensões específicas do Linux provavelmente deve ser explicitamente observado, para que algum leitor futuro que tente resolver um problema semelhante em um sistema não-Linux seja confundido.dd
na minha máquina, com tamanhos de bloco de 1k a 512M. Lendo de um SSD Intel 750, o desempenho ideal (cerca de 1300MiB / s) foi alcançado em blocos de 2MiB, correspondendo aproximadamente aos seus resultados. Tamanhos maiores de blocos não ajudaram nem atrapalharam. Lendo de/dev/zero
, o desempenho ideal (quase 20GiB / s) foi nos blocos de 64KiB e 128KiB; blocos menores e maiores diminuíram o desempenho, correspondendo aproximadamente ao meu comentário anterior. Conclusão: referência para a sua situação real. E, é claro, nenhum de nós/dev/random
dd
é mais rápido. Uma rápida análise mostrou quehead
usa 8KiB lê e duas gravações 4KiB, o que é interessante (GNU coreutils 8.26 no Debian 9.6 / Linux 4.8).head
velocidades são de fato em algum lugar entredd bs=4k
edd bs=8k
.head
as velocidades caíram ~ 40% em comparação comdd if=/dev/zero bs=64k
e ~ 25% em comparação comdd if=/dev/nvme0n1 bs=2M
. As leituras/dev/zero
de, obviamente, são mais limitadas à CPU, mas para as filas de E / S SSD também desempenham um papel. É uma diferença maior do que eu esperava.dd
pode ler menos queibs
(nota:bs
especifica ambosibs
eobs
), a menos queiflag=fullblock
seja especificado.0+1 records in
indica que os0
blocos completos e1
parciais foram lidos. No entanto, qualquer bloqueio total ou parcial aumenta o contador.Eu não sei o mecanismo exato que fazEditar: esta resposta simultânea explica o mecanismo que torna add
ler um bloco que é menor do que1G
neste caso particular. Eu acho que qualquer bloco é lido na memória antes de ser gravado, portanto, o gerenciamento de memória pode interferir (mas isso é apenas um palpite).dd
leitura de um bloco menor do que1G
nesse caso específico.Enfim, eu não recomendo tão grande
bs
. Eu usariabs=1M count=1024
. O mais importante é: semiflag=fullblock
nenhuma tentativa de leitura, a leitura pode ser menor queibs
(a menos queibs=1
eu ache que isso é bastante ineficiente).Portanto, se você precisar ler uma quantidade exata de dados, use
iflag=fullblock
. Notaiflag
não é requerida pelo POSIX,dd
talvez você não a suporte. De acordo com esta resposta,ibs=1
provavelmente é a única maneira POSIX de ler um número exato de bytes. Obviamente, se você alteraribs
, será necessário recalcular ocount
. No seu caso, diminuiribs
para32M
ou menos provavelmente resolverá o problema, mesmo sem eleiflag=fullblock
.No meu Kubuntu, eu corrigia seu comando assim:
fonte