48 votos

DD es producir un archivo al azar de 32 MB en lugar de 1 GB

Quería producir un 1 GB de archivo aleatorio, así que he usado siguiente comando.

dd if=/dev/urandom of=output bs=1G count=1

Pero en lugar de eso cada vez que ejecuto este comando me sale una de 32 MB archivo:

<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

Lo que está mal?

EDITAR:

Gracias a las excelentes respuestas en este tema me vino con la solución que se lee de 32 trozos de 32 MB que hace 1GB:

dd if=/dev/urandom of=output bs=32M count=32

Otra solución se da en la que se lee 1 GB directamente a la memoria y, a continuación, escribe en el disco. Esta solución tiene un montón de memoria, por lo que no es preferente:

dd if=/dev/urandom of=output bs=1G count=1 iflag=fullblock

91voto

Nick Dixon Puntos 154

bs, el tamaño de búfer, significa que el tamaño de una sola read() llamada realizada por dd.

(Por ejemplo, bs=1M count=1 y bs=1k count=1k el resultado será un 1 archivo MiB, pero la primera versión va a hacer en un solo paso, mientras que el segundo lo hará en 1024 trozos pequeños.)

Los archivos regulares, se puede leer en casi cualquier tamaño de búfer (siempre que el búfer se ajusta en la RAM), pero los dispositivos y "virtual" de los archivos de trabajo a menudo muy cerca de las llamadas individuales y de tener alguna restricción arbitraria de la cantidad de datos que se va a producir por leer ().

Para /dev/urandom, este límite se define en urandom_read() en drivers/char/random.c:

#define ENTROPY_SHIFT 3

static ssize_t
urandom_read(struct file *file, char __user *buf, size_t nbytes, loff_t *ppos)
{
    nbytes = min_t(size_t, nbytes, INT_MAX >> (ENTROPY_SHIFT + 3));
    ...
}

Esto significa que cada vez que se llama a la función, se sujetará al tamaño solicitado a 33554431 bytes.

De forma predeterminada, a diferencia de la mayoría de las otras herramientas, dd no volverá a intentar después de recibir menos datos que solicita, usted recibe el 32 MiB y eso es todo. (Para reintentar automáticamente, como en el de Kamil respuesta, deberá especificar iflag=fullblock.)


Tenga en cuenta también que "el tamaño de una sola lectura()" significa que todo el buffer debe caber en la memoria a la vez, tan masiva tamaños de bloque, también corresponden a la masiva el uso de la memoria por dd.

Y todo es inútil, porque por lo general no es aumentar el rendimiento cuando se va por encima de ~16-32 MiB bloques – syscalls no son la parte lenta aquí, el generador de números aleatorios.

Así, por simplicidad, sólo se uso head -c 1G /dev/urandom > output.

21voto

Kamil Maciorowski Puntos 897

dd puede leer menos de ibs (nota: bs especifica tanto ibs y obs), a menos iflag=fullblock está especificado. 0+1 records in indica que 0 bloques completos y 1 parcial bloque de lectura. Sin embargo, cualquier total o parcial del bloque aumenta el contador.

No sé el mecanismo exacto que hace que dd leer un bloque que está a menos de 1G en este caso en particular. Supongo que cualquier bloque de lectura a la memoria antes de que sea por escrito, por lo que la gestión de la memoria puede interferir (pero esto es sólo una suposición). Edit: este concurrente respuesta explica el mecanismo que hace que dd leer un bloque que está a menos de 1G en este caso en particular.

De todos modos, no recomiendo esos grandes bs. Yo usaría bs=1M count=1024. La cosa más importante es: sin iflag=fullblock cualquier intento de lectura puede leer menos de ibs (a menos ibs=1, creo, esto es bastante ineficiente).

Así que si usted necesita para leer cierta cantidad exacta de datos, uso iflag=fullblock. Nota iflag no es requerido por POSIX, su dd no la admiten. De acuerdo a esta respuesta ibs=1 es probablemente la única POSIX para leer un número exacto de bytes. Por supuesto, si usted cambie ibs entonces usted necesita para volver a calcular el count. En su caso la reducción de ibs a 32M o menos probablemente va a solucionar el problema, incluso sin iflag=fullblock.

En mi Kubuntu me gustaría arreglar su comando como este:

dd if=/dev/urandom of=output bs=1M count=1024 iflag=fullblock

EnMiMaquinaFunciona.com

EnMiMaquinaFunciona es una comunidad de administradores de sistemas en la que puedes resolver tus problemas y dudas.
Puedes consultar las preguntas de otros sysadmin, hacer tus propias preguntas o resolver las de los demás.

Powered by: