O dd pode ser usado para arquivos pequenos regulares?

O dd pode ser usado para arquivos pequenos regulares?

Homem dd:

dd - converte e copia um arquivo

Estou inclinado a usar dd. Estranhamente, depois de copiar o arquivo de texto de 1 byte, fica muito menor:

$ 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

Ele disse 1 byte copied, por que o fim do arquivo desapareceu?

Adicionado:

Como o comentário sugeriu, conv=notrunccorrige. Mas de man:

conv=CONVS converte o arquivo de acordo com a lista de símbolos separados por vírgula

Eu não queria converter um arquivo. Ao ler sobre a cópia de dispositivos de bloco, não vi esse operando. É sempre necessário quando nem todos os arquivos (por exemplo, um bloco de 512 bytes em /dev/sdb: disco USB) são alterados?

Responder1

O que você está fazendo é isso:

block_size=1; 
dd ... count=1 seek=2 skip=2 bs=$block_size; 

você está pedindo ddpara copiar apenas um byte. Mas, por padrão, ele trunca o arquivo de saída, para que o final do arquivo seja o ddfinal.

$ 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

A página de manual do GNU que tenho não parece dizer isso explicitamente, masa descrição POSIX faz:

of=file
Especifique o nome do caminho de saída; [...] Se seek=exprfor especificado, mas conv=notruncnão for, o efeito da cópia será preservar os blocos no arquivo de saída sobre os quais dd procura, mas nenhuma outra parte do arquivo de saída será preservada. (Se o tamanho da busca mais o tamanho do arquivo de entrada for menor que o tamanho anterior do arquivo de saída, o arquivo de saída deverá ser encurtado pela cópia.[...])

Para evitar isso, adicione a conv=notruncopção:

notrunc
não trunque o arquivo de saída

$ 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

notruncnão faz com que ele modifique os dados que realmente são copiados, portanto não é uma "conversão" nesse sentido, mesmo que seja considerado um sinalizador para conv.

Observe que if count=é fornecido, ddfaz exatamente esse número read()de chamadas, o que significa que se você ler de um dispositivo que pode fornecer leituras curtas, a quantidade de dados realmente lidos não será counttimes bs.

Responder2

Deveria ter olhado a documentação completa man dd:

Full documentation at: <https://www.gnu.org/software/coreutils/dd>
       or available locally via: info '(coreutils) dd invocation'

'of=FILE' Grava em FILE em vez da saída padrão. A menos que 'conv=notrunc' seja fornecido, 'dd' trunca FILE para zero bytes (ou o tamanho especificado com 'seek=').

informação relacionada