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

dden absoluto. Yo usaríahead,catorsyncen su lugar casi siempre. Y su pregunta es una de las razones por las cuales las alternativas son generalmente más seguras.headno puede hacer esta tarea sin la-copción que no está en POSIX . No conozco ninguna versióncatque pueda resolver esto.rsyncEs 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/urandomtampoco 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=1ybs=1k count=1kresultará 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=fullblockes una extensión de GNU para laddutilidad 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.ddmi 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/randomddes más rápido. Una versión rápida mostró queheadusa lecturas de 8KiB y dos escrituras de 4KiB, lo cual es interesante (GNU coreutils 8.26 en Debian 9.6 / Linux 4.8).headlas velocidades están en algún lugar entredd bs=4kydd bs=8k.headlas velocidades disminuyeron ~ 40% en comparación condd if=/dev/zero bs=64ky 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.ddpuede leer menos deibs(nota:bsespecifica ambosibsyobs), a menos queiflag=fullblockse especifique.0+1 records inindica que se leyeron0bloques completos y1bloque 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 queddleer un bloque sea menor que1Gen 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).ddleer un bloque sea menor que1Gen este caso particular.De todos modos, no recomiendo tan grande
bs. Me gustaría utilizarbs=1M count=1024. Lo más importante es: siniflag=fullblockningú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. Notaiflagno es requerida por POSIX, esddposible que no la admita. Según esta respuesta,ibs=1es 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ónibsa32Mo menos probable que se solucionará el problema, incluso siniflag=fullblock.En mi Kubuntu arreglaría tu comando así:
fuente