Quería producir un archivo aleatorio de 1 GB, así que utilicé el siguiente comando.
dd if=/dev/urandom of=output bs=1G count=1
Pero cada vez que ejecuto este comando obtengo un archivo 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
¿Qué está mal?
EDITAR:
Gracias a las excelentes respuestas en este tema, llegué con una solución que lee 32 fragmentos de 32 MB de tamaño, lo que hace que 1 GB:
dd if=/dev/urandom of=output bs=32M count=32
Se dio otra solución que lee 1 GB directamente en la memoria y luego escribe en el disco. Esta solución toma mucha memoria, por lo que no se prefiere:
dd if=/dev/urandom of=output bs=1G count=1 iflag=fullblock
script
dd
random-number-generator
Trismegistos
fuente
fuente
dd
en absoluto. Yo usaríahead
,cat
orsync
en su lugar casi siempre. Y su pregunta es una de las razones por las cuales las alternativas son generalmente más seguras.head
no puede hacer esta tarea sin la-c
opción que no está en POSIX . No conozco ninguna versióncat
que pueda resolver esto.rsync
Es una utilidad completamente no estándar. Eso no está ni aquí ni allá; hojeando su página de manual, tampoco veo cómo puede resolver este problema./dev/urandom
tampoco está en POSIX ...Respuestas:
bs
, el tamaño del búfer, significa el tamaño de una sola llamada read () realizada por dd.(Por ejemplo, tanto
bs=1M count=1
ybs=1k count=1k
resultará en un archivo de 1 MiB, pero la primera versión lo hará en un solo paso, mientras que la segunda lo hará en 1024 trozos pequeños.)Los archivos normales se pueden leer en casi cualquier tamaño de búfer (siempre que el búfer se ajuste a la RAM), pero los dispositivos y los archivos "virtuales" a menudo funcionan muy cerca de las llamadas individuales y tienen una restricción arbitraria de la cantidad de datos que producirán por llamada read ().
Para
/dev/urandom
, este límite se define en urandom_read () en drivers / char / random.c :Esto significa que cada vez que se llama a la función, fijará el tamaño solicitado a 33554431 bytes.
De manera predeterminada, a diferencia de la mayoría de las otras herramientas, dd no volverá a intentarlo después de recibir menos datos de los solicitados: obtiene el 32 MiB y listo. (Para que vuelva a intentarlo automáticamente, como en la respuesta de Kamil, deberá especificar
iflag=fullblock
).Tenga en cuenta también que "el tamaño de una sola lectura ()" significa que todo el búfer debe caber en la memoria a la vez, por lo que los tamaños de bloque masivos también corresponden al uso masivo de memoria por parte de dd .
Y todo es inútil porque generalmente no obtendrá ningún rendimiento cuando supere ~ 16–32 bloques MiB: las llamadas al sistema no son la parte lenta aquí, sino el generador de números aleatorios.
Entonces, por simplicidad, solo use
head -c 1G /dev/urandom > output
.fuente
iflag=fullblock
es una extensión de GNU para ladd
utilidad POSIX . Como la pregunta no especifica Linux, creo que el uso de extensiones específicas de Linux probablemente debería notarse explícitamente para que algún futuro lector que intente resolver un problema similar en un sistema que no sea Linux se confunda.dd
mi máquina, con tamaños de bloque de 1k a 512M. Leyendo de un SSD Intel 750, se logró un rendimiento óptimo (aproximadamente 1300MiB / s) en bloques de 2MiB, que coinciden aproximadamente con sus resultados. Los tamaños de bloque más grandes no ayudaron ni obstaculizaron. Leyendo/dev/zero
, el rendimiento óptimo (casi 20GiB / s) estaba en bloques de 64KiB y 128KiB; tanto pequeños y grandes bloques disminución del rendimiento, coincidiendo más o menos mi comentario anterior. En pocas palabras: punto de referencia para su situación real. Y, por supuesto, ninguno de nosotros/dev/random
dd
es más rápido. Una versión rápida mostró quehead
usa lecturas de 8KiB y dos escrituras de 4KiB, lo cual es interesante (GNU coreutils 8.26 en Debian 9.6 / Linux 4.8).head
las velocidades están en algún lugar entredd bs=4k
ydd bs=8k
.head
las velocidades disminuyeron ~ 40% en comparación condd if=/dev/zero bs=64k
y disminuyeron ~ 25% en comparación condd if=/dev/nvme0n1 bs=2M
. Las lecturas de/dev/zero
, por supuesto, están más limitadas por la CPU, pero para el SSD I / O queing también juega un papel. Es una diferencia más grande de lo que esperaba.dd
puede leer menos deibs
(nota:bs
especifica ambosibs
yobs
), a menos queiflag=fullblock
se especifique.0+1 records in
indica que se leyeron0
bloques completos y1
bloque parcial. Sin embargo, cualquier bloqueo total o parcial aumenta el contador.No sé el mecanismo exacto que hace queEditar: esta respuesta concurrente explica el mecanismo que hace quedd
leer un bloque sea menor que1G
en este caso particular. Supongo que cualquier bloque se lee en la memoria antes de que se escriba, por lo que la gestión de la memoria puede interferir (pero esto es solo una suposición).dd
leer un bloque sea menor que1G
en este caso particular.De todos modos, no recomiendo tan grande
bs
. Me gustaría utilizarbs=1M count=1024
. Lo más importante es: siniflag=fullblock
ningún intento de lectura, puede leer menos deibs
(a menosibs=1
, creo, que esto es bastante ineficiente).Entonces, si necesita leer una cantidad exacta de datos, úsela
iflag=fullblock
. Notaiflag
no es requerida por POSIX, esdd
posible que no la admita. Según esta respuesta,ibs=1
es probablemente la única forma POSIX de leer un número exacto de bytes. Por supuesto, si cambiaibs
, deberá volver a calcular elcount
. En su caso la reducciónibs
a32M
o menos probable que se solucionará el problema, incluso siniflag=fullblock
.En mi Kubuntu arreglaría tu comando así:
fuente