
Creo un archivo de 1TB con datos aleatorios con dd if=/dev/urandom of=file bs=1M count=1000000
. Ahora verifico kill -SIGUSR1 <PID>
el progreso y obtengo lo siguiente:
691581+0 Datensätze ein
691580+0 Datensätze aus
725174190080 Bytes (725 GB) kopiert, 86256,9 s, 8,4 MB/s
800950+1 Datensätze ein
800950+0 Datensätze aus
839856947200 Bytes (840 GB) kopiert, 99429,5 s, 8,4 MB/s
dd: warning: partial read (809620 bytes); suggest iflag=fullblock
803432+1 Datensätze ein
803431+1 Datensätze aus
842459273876 Bytes (842 GB) kopiert, 99791,3 s, 8,4 MB/s
No puedo interpretar la advertencia. ¿Qué dice? ¿Mi archivo es realmente aleatorio después de la advertencia o hay algún problema? ¿Qué significa +0 o +1 en 800950+1 Datensätze ein
y 800950+0 Datensätze aus
significa? Después de la advertencia es +1. ¿Es un recuento de errores?
Respuesta1
Resumen: dd
es una herramienta de mal humor que es difícil de usar correctamente. No lo uses, a pesar de los numerosos tutoriales que así te lo indican. dd
tiene una vibra de “credibilidad callejera Unix”, pero si realmente entiendes lo que estás haciendo, sabrás que no deberías tocarlo con un poste de 10 pies.
dd
realiza una única llamada a la read
llamada del sistema por bloque (definida por el valor de bs
). No hay garantía de que la read
llamada al sistema devuelva tantos datos como el tamaño del búfer especificado. Esto tiende a funcionar para archivos normales y dispositivos de bloque, pero no para tuberías y algunos dispositivos de caracteres. Ver¿Cuándo es adecuado dd para copiar datos? (o, cuando son parciales lectura() y escritura())para más información. Si la read
llamada al sistema devuelve menos de un bloque completo, dd
transfiere un bloque parcial. Todavía copia la cantidad especificada de bloques, por lo que la cantidad total de bytes transferidos es menor que la solicitada.
La advertencia sobre una "lectura parcial" le dice exactamente esto: una de las lecturas fue parcial, por lo que dd
transfirió un bloque incompleto. En el conteo de bloques, +1
significa que un bloque fue leído parcialmente; Dado que el recuento de salida es +0
, todos los bloques se escribieron como leídos.
Esto no afecta la aleatoriedad de los datos: todos los bytes que dd
se escriben son bytes de los que se lee /dev/urandom
. Pero obtuviste menos bytes de los esperados.
Linux /dev/urandom
admite solicitudes grandes y arbitrarias (fuente:extract_entropy_user
en drivers/char/random.c
), por lo que dd
normalmente es seguro leerlo. Sin embargo, leer grandes cantidades de datos lleva tiempo. Si el proceso recibe una señal, la read
llamada al sistema regresa antes de llenar su búfer de salida. Este es un comportamiento normal y se supone que las aplicaciones llaman read
en un bucle; dd
no hace esto, por razones históricas ( dd
los orígenes de 's son confusos, pero parece haber comenzado como una herramienta para acceder a cintas, que tienen requisitos peculiares, y nunca se adaptó para ser una herramienta de propósito general). Cuando verifica el progreso, esto envía al dd
proceso una señal que interrumpe la lectura. Tiene la opción de saber cuántos bytes dd
se copiarán en total (asegúrese de no interrumpirlo, sin verificación de progreso, sin suspensión) o saber cuántos bytes dd
se han copiado hasta el momento, en cuyo caso no podrá saber cuántos más. bytes que copiará.
la versión dedd
en GNU coreutils(como se encuentra en Linux no integrado y en Cygwin) tiene un indicador fullblock
que indica dd
llamar read
en un bucle (y lo mismo para write
) y, por lo tanto, siempre transferir bloques completos. El mensaje de error sugiere que lo utilice; siempre debe usarlo (tanto en los indicadores de entrada como de salida), excepto en circunstancias muy especiales (principalmente al acceder a cintas); si dd
es que lo usa, es decir: generalmente hay mejores soluciones (ver más abajo).
dd if=/dev/urandom iflag=fullblock of=file bs=1M count=1000000
Otra forma posible de estar seguro de lo que dd
funcionará es pasar un tamaño de bloque de 1. Luego podrá saber cuántos bytes se copiaron del recuento de bloques, aunque no estoy seguro de qué sucederá si read
se interrumpe a antes de leer el primero. byte (lo cual no es muy probable en la práctica, pero puede suceder). Sin embargo, incluso si funciona, es muy lento.
El consejo general sobre su uso dd
esno utilicedd
. Aunque dd
a menudo se anuncia como un comando de bajo nivel para acceder a dispositivos, en realidad no es tal cosa: toda la magia ocurre en la /dev/…
parte del archivo del dispositivo (la), dd
es solo una herramienta común y corriente con un alto potencial de uso indebido que resulta en pérdida de datos. . En la mayoría de los casos, existe una forma más sencilla y segura de hacer lo que quieras, al menos en Linux.
Por ejemplo, para leer una cierta cantidad de bytes al comienzo de un archivo, simplemente llame a head
:
head -c 1000000m </dev/urandom >file
Hice una prueba comparativa rápida en mi máquina y no observé ninguna diferencia de rendimiento entre dd
un tamaño de bloque grande y head
.
Si necesita omitir algunos bytes al principio, ingrese tail
a head
:
dd if=input of=output count=C bs=B seek=S
<input tail -c +$((S*B+1)) | head -c $((C*B)) >output
Si desea ver el progreso, llame lsof
para ver el desplazamiento del archivo. Esto solo funciona en un archivo normal (el archivo de salida en su ejemplo), no en un dispositivo de caracteres.
lsof -a -p 1234 -d 1
cat /proc/1234/fdinfo/1
Puedes llamarpv
para obtener un informe de progreso (mejor que dd
el de), a expensas de un elemento adicional en proceso (en cuanto al rendimiento, es apenas perceptible).
Respuesta2
La advertencia ocurre cuando dd
no se pudieron obtener suficientes datos para completar un bloque en una sola lectura. Esto sucede con fuentes de datos erráticas o lentas, o fuentes que escriben datos en unidades más pequeñas que el tamaño de bloque solicitado.
No hay ningún problema con la integridad de los datos, pero el problema es que dd
una lectura parcial todavía cuenta como un bloque de lectura.
Si no está utilizando la count
opción, la advertencia apenas importa, es sólo una consideración de rendimiento. Pero con count
, no obtendrá la cantidad de datos que solicitó. Debido a lecturas parciales, of
será más pequeño que count*bs
al final.
Entonces, cuando usas count
, técnicamente siempre debes usarlo iflag=fullblock
también.
Debería +x
ser el número de bloques parciales.
Respuesta3
< /dev/urandom \
dd ibs=4k obs=64k |
dd bs=64k count=16000000 >file
^Eso simplemente funcionará. La información errónea que se tiene aquí es manifiestamente falsa. dd
Los buffers sonexplícitoy así, para almacenar en búfer la entrada acontarocurrencias que necesita almacenar en buffer explícitamente. Eso es todo. No compres la mierda.