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 del read
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 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 la read
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
in drivers/char/random.c
), por dd
lo que normalmente es seguro cuando se lee. 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 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 al dd
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 se dd
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 bandera fullblock
que le dice dd
que llame read
en un bucle (y lo mismo para write
) 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 usa dd
, es decir: generalmente hay mejores soluciones (consulte a continuación).
dd if=/dev/urandom iflag=fullblock oflag=fullblock of=file bs=1M count=1000000
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á si read
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 a dd
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
:
head -c 1000000m </dev/urandom >file
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 y head
.
Si necesita omitir algunos bytes al principio, diríjase 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
Puede llamar pv
para obtener un informe de progreso (mejor que dd
's), a expensas de un elemento adicional en la tubería (en cuanto al rendimiento, es apenas perceptible).