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=notrunc
corrige. 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 dd
para copiar apenas um byte. Mas, por padrão, ele trunca o arquivo de saída, para que o final do arquivo seja o dd
final.
$ 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; [...] Seseek=expr
for especificado, masconv=notrunc
nã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=notrunc
opçã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
notrunc
nã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, dd
faz 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á count
times 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=').