De la especificación :
- Si
bs=exprse especifica el operando y no se solicitan conversiones que no sean sync, noerroro notruncse soliciten, los datos devueltos de cada bloque de entrada se escribirán como un bloque de salida separado; Si el read()retorno es inferior a un bloque completo y syncno se especifica la conversión, el bloque de salida resultante será del mismo tamaño que el bloque de entrada.
Entonces esto es probablemente lo que causa tu confusión. Sí, debido a que ddestá diseñado para el bloqueo, de manera predeterminada, los read()s parciales se asignarán 1: 1 a write()s parciales , o bien se syncdotarán de NUL de relleno de cola o caracteres de espacio bs=cuando conv=syncse especifique.
Esto significa que ddes seguro de usar para copiar datos (sin riesgo de corrupción debido a una lectura o escritura parcial) en todos los casos, excepto uno en el que está limitado arbitrariamente por un count=argumento, porque de lo contrario ddfelizmente write()su salida en bloques de tamaño idéntico a aquellos en los que su entrada fue read()hasta que read()la atravesó por completo. E incluso esta advertencia es sólo es cierto cuando bs=se especifica o obs=se no se especifica, como el siguiente oración en los estados de especificaciones:
- Si
bs=exprno se especifica el operando , o si se solicita una conversión diferente a sync, noerroro notruncse solicita, la entrada se procesará y se recopilará en bloques de salida de tamaño completo hasta llegar al final de la entrada.
Sin ibs=y / o obs=argumentos esto no puede importa - porque ibsy obsson a la vez el mismo tamaño por defecto. Sin embargo, puede ser explícito sobre el almacenamiento en búfer de entrada especificando diferentes tamaños para cualquiera y no especificando bs= (porque tiene prioridad) .
Por ejemplo, si haces:
IN| dd ibs=1| OUT
... entonces un POSIX lo ddhará write()en fragmentos de 512 bytes al recopilar cada read()byte individualmente en un solo bloque de salida.
De lo contrario, si lo haces ...
IN| dd obs=1kx1k| OUT
... un POSIX ddtendrá read() un máximo de 512 bytes a la vez, pero write()cada bloque de salida de un tamaño de megabyte (el kernel permite y exceptúa posiblemente el último, porque eso es EOF) completo al recopilar la entrada en bloques de salida de tamaño completo .
Sin embargo, también de la especificación:
count=n
- Copie solo n bloques de entrada.
count=asigna a i?bs=bloques, por lo que para manejar un límite arbitrario de forma count=portátil necesitarás dos dds. La forma más práctica de hacerlo con dos dds es canalizando la salida de uno en la entrada de otro, lo que seguramente nos coloca en el ámbito de la lectura / escritura de un archivo especial independientemente del tipo de entrada original.
Una tubería IPC significa que al especificar [io]bs=argumentos que, para hacerlo de manera segura, debe mantener dichos valores dentro del PIPE_BUFlímite definido del sistema . POSIX establece que el núcleo del sistema sólo debe garantizar atómicas read()s y write()s dentro de los límites de PIPE_BUFcomo se define en limits.h. POSIX garantiza que PIPE_BUFsea al menos ...
{_POSIX_PIPE_BUF}
- Número máximo de bytes que se garantiza que son atómicos cuando se escribe en una tubería.
- Valor: 512
... (que también es el ddtamaño de bloque de E / S predeterminado ) , pero el valor real suele ser al menos 4k. En un sistema Linux actualizado es, por defecto, 64k.
Entonces, cuando configura sus ddprocesos, debe hacerlo en un factor de bloque basado en tres valores:
- bs = (obs =
PIPE_BUFo menor)
- n = número total deseado de bytes leídos
- cuenta = n / bs
Me gusta:
yes | dd obs=1k | dd bs=1k count=10k of=/dev/null
10240+0 records in
10240+0 records out
10485760 bytes (10 MB) copied, 0.1143 s, 91.7 MB/s
Tiene que sincronizar i / ow / ddpara manejar entradas no buscables. En otras palabras, haga explícitos los amortiguadores de tubería y dejarán de ser un problema. Para eso ddes eso . La cantidad desconocida aquí es yesel tamaño del búfer, pero si bloquea eso a una cantidad conocida con otra, ddentonces una pequeña multiplicación informada puede ser dd segura de usar para copiar datos (sin riesgo de corrupción debido a una lectura o escritura parcial) incluso cuando limite arbitrariamente la entrada con count=cualquier tipo de entrada arbitraria en cualquier sistema POSIX y sin perder un solo byte.
Aquí hay un fragmento de la especificación POSIX :
ibs=expr
- Especifique el tamaño del bloque de entrada, en bytes, por (el valor predeterminado es 512) .
expr
obs=expr
- Especifique el tamaño del bloque de salida, en bytes, por (el valor predeterminado es 512) .
expr
bs=expr
- Establezca los tamaños de bloque de entrada y salida en
exprbytes, reemplazando ibs=y obs=. Si no se especifica otra conversión que sync, noerrory notruncse especifica, cada bloque de entrada se copiará a la salida como un bloque único sin agregar bloques cortos.
También encontrarás algo de esto mejor explicado aquí .