Hombre dd
:
dd - convierte y copia un archivo
Me inclino por usar dd
. Curiosamente, después de copiar el archivo de texto de 1 byte se vuelve mucho más pequeño:
$ block_size=1; device_to_edit=/media/ramdrive/a; device_from=/media/ramdrive/b; echo "aaaaaaaaaa">$device_to_edit; echo "bbbbbbbbbb">$device_from; cat $device_to_edit; cat $device_from; dd if=$device_from of=$device_to_edit count=1 seek=2 skip=2 bs=$block_size; cat $device_to_edit
aaaaaaaaaa
bbbbbbbbbb
1+0 records in
1+0 records out
1 byte copied, 0,000156688 s, 6,4 kB/s
aab
Decía 1 byte copied
, ¿por qué desapareció el final del archivo?
Agregado:
Como sugirió el comentario, conv=notrunc
lo soluciona. Pero de donde man
:
conv=CONVS convierte el archivo según la lista de símbolos separados por comas
No quería convertir un archivo. Al leer sobre la copia de dispositivos de bloque, no vi este operando. ¿Siempre es necesario cuando no se cambian todos los archivos (por ejemplo, un bloque de 512 bytes en /dev/sdb: disco USB)?
Respuesta1
Lo que estás haciendo es esto:
block_size=1;
dd ... count=1 seek=2 skip=2 bs=$block_size;
estás pidiendo dd
copiar solo un byte. Pero, de forma predeterminada, trunca el archivo de salida, de modo que el final del archivo esté donde dd
terminó.
$ echo abcdefgh > test1
$ echo 12345678 > test2
$ dd count=1 bs=1 skip=2 seek=2 if=test1 of=test2
1+0 records in
1+0 records out
1 byte copied, 0.000179375 s, 5.6 kB/s
$ cat test2; echo
12c
La página de manual de GNU que tengo no parece decir eso explícitamente, perola descripción POSIX no:
of=file
Especifique el nombre de la ruta de salida; [...] Siseek=expr
se especifica, peroconv=notrunc
no lo es, el efecto de la copia será preservar los bloques en el archivo de salida sobre los que dd busca, pero no se conservará ninguna otra parte del archivo de salida. (Si el tamaño de la búsqueda más el tamaño del archivo de entrada es menor que el tamaño anterior del archivo de salida, el archivo de salida se acortará con la copia.[...])
Para evitarlo, agregue la conv=notrunc
opción:
notrunc
no truncar el archivo de salida
$ echo 12345678 > test2
$ dd conv=notrunc count=1 bs=1 skip=2 seek=2 if=test1 of=test2
1+0 records in
1+0 records out
1 byte copied, 0.00019385 s, 5.2 kB/s
$ cat test2
12c45678
notrunc
no hace que modifique los datos que realmente se copian, por lo que no es una "conversión" en ese sentido, aunque se toma como una bandera para conv
.
Tenga en cuenta que si count=
se proporciona, dd
realiza exactamente esa cantidad de read()
llamadas, lo que significa que si lee desde un dispositivo que puede realizar lecturas breves, la cantidad de datos realmente leídos no es count
multiplicada bs
.
Respuesta2
Debería haber mirado la documentación completa man dd
:
Full documentation at: <https://www.gnu.org/software/coreutils/dd>
or available locally via: info '(coreutils) dd invocation'
'of=FILE' Escribe en ARCHIVO en lugar de en la salida estándar. A menos que se proporcione 'conv=notrunc', 'dd' trunca el ARCHIVO a cero bytes (o el tamaño especificado con 'seek=').