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 en800950+1 Datensätze ein
y 800950+0 Datensätze aus
significa? Después de la advertencia es +1. ¿Es una cuenta de errores?
LC_ALL=C
delante del comando, comoLC_ALL=C dd if=...
Respuestas:
Resumen:
dd
es una herramienta irritable que es difícil de usar correctamente. No lo uses, a pesar de los numerosos tutoriales que te lo dicen.dd
tiene un ambiente 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 sola llamada a la llamada delread
sistema por bloque (definida por el valor debs
). No hay garantía de que laread
llamada al sistema devuelva tantos datos como el tamaño de búfer especificado. Esto tiende a funcionar para archivos normales y dispositivos de bloque, pero no para tuberías y algunos dispositivos de caracteres. Consulte ¿ Cuándo es adecuado dd para copiar datos? (o, cuando se lee () y escribe () parcial) para obtener más información. Si laread
llamada del sistema devuelve menos de un bloque completo,dd
transfiere un bloque parcial. Todavía copia el número especificado de bloques, por lo que la cantidad total de bytes transferidos es inferior a 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 los recuentos de bloques,+1
significa que un bloque se leyó parcialmente;+0
Como el recuento de salida es , todos los bloques se escribieron como leídos.Esto no afecta la aleatoriedad de los datos: todos los bytes que se
dd
escriben son bytes de los que se lee/dev/urandom
. Pero tienes menos bytes de lo esperado.Linux
/dev/urandom
acomoda solicitudes grandes arbitrarias (fuente:extract_entropy_user
indrivers/char/random.c
), pordd
lo que normalmente es seguro cuando se lee. Sin embargo, leer grandes cantidades de datos lleva tiempo. Si el proceso recibe una señal, laread
llamada al sistema regresa antes de llenar su búfer de salida. Este es un comportamiento normal, y se supone que las aplicaciones llamanread
en un bucle;dd
no hace esto, por razones históricas (dd
los orígenes son turbios, pero parece haber comenzado como una herramienta para acceder a las cintas, que tienen requisitos particulares, y nunca fue adaptada para ser una herramienta de uso general). Cuando verifica el progreso, esto envía aldd
proceso una señal que interrumpe la lectura. Puedes elegir entre saber cuántos bytesdd
copiará en total (asegúrese de no interrumpirlo, sin verificación de progreso, sin suspensión), o saber cuántos bytes sedd
han copiado hasta el momento, en cuyo caso no puede saber cuántos bytes más copiará.La versión de
dd
en GNU coreutils (como se encuentra en Linux no incrustado y en Cygwin) tiene una banderafullblock
que le dicedd
que llameread
en un bucle (y lo mismo parawrite
) y, por lo tanto, siempre transfiera bloques completos. El mensaje de error sugiere que lo use; siempre debe usarlo (tanto en los indicadores de entrada como en los de salida), excepto en circunstancias muy especiales (principalmente al acceder a cintas); si lo usadd
, es decir: generalmente hay mejores soluciones (consulte a continuación).Otra forma posible de estar seguro de lo
dd
que hará es pasar un tamaño de bloque de 1. Luego, puede saber cuántos bytes se copiaron del recuento de bloques, aunque no estoy seguro de qué sucederá siread
se interrumpe un antes de leer el primero. byte (que no es muy probable en la práctica pero puede suceder). Sin embargo, incluso si funciona, esto es muy lento.El consejo general sobre el uso
dd
es no usardd
. Aunque add
menudo se anuncia como un comando de bajo nivel para acceder a dispositivos, de hecho no es tal cosa: toda la magia ocurre en la parte del archivo del dispositivo (la/dev/…
),dd
es solo una herramienta ordinaria con un alto potencial de mal uso que resulta en la pérdida de datos . En la mayoría de los casos, hay una manera más simple y segura de hacer lo que quiere, al menos en Linux.Por ejemplo, para leer un cierto número de bytes al comienzo de un archivo, simplemente llame
head
:Hice un punto de referencia rápido en mi máquina y no observé ninguna diferencia de rendimiento entre
dd
un gran tamaño de bloque yhead
.Si necesita omitir algunos bytes al principio, diríjase
tail
ahead
: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.Puede llamar
pv
para obtener un informe de progreso (mejor quedd
's), a expensas de un elemento adicional en la tubería (en cuanto al rendimiento, es apenas perceptible).fuente
dd
comando que no me di cuenta que necesitaba saber. Gracias.dd
se puede utilizar de forma segura, gracias a sufullblock
opción. Pero si tienes GNU coreutils no necesitasdd
mucho. Los "derivados" como no lodcfldd
son , no sufren sus defectos de diseño, por lo que mi respuesta no se aplica a ellos. Una vasta, gran mayoría de las personas que lo usan no se han tomado el tiempo suficiente para entenderlo (a lo sumo, se han tomado el tiempo para pensar que lo entienden) y la forma en que lo usan conduce a la pérdida de datos.dd
dd
La advertencia se produce cuando
dd
no se pueden obtener suficientes datos para llenar 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
todavía se considera una lectura parcial como un bloque de lectura.Si no está utilizando la
count
opción, la advertencia no importa, es solo una consideración de rendimiento. Pero concount
, no obtendrá la cantidad de datos que solicitó. Debido a lecturas parciales,of
será más pequeño quecount*bs
al final.Entonces, cuando lo usa
count
, técnicamente siempre debe usarloiflag=fullblock
también.El
+x
debería ser el número de bloques parciales.fuente
^ Eso solo funcionará. La información errónea que de otro modo tenía aquí es manifiestamente falsa.
dd
Los almacenamientos intermedios son explícitos y, por lo tanto, para almacenar la entrada para contar las ocurrencias, debe almacenar explícitamente. Eso es todo. No compres el fud.fuente