Linux / Comando dd: copiar blocos, extrair trechos e verificar bytes

O comando GNU dd copia dados da entrada para a saída, permitindo escolher blocos, deslocamentos e conversões. if= indica de onde ler e of= onde gravar; um destino errado pode sobrescrever dados imediatamente. Comece com arquivos pequenos e confira os bytes copiados antes de planejar qualquer operação em dispositivos.

Os exemplos usam Bash e GNU Coreutils. Confira dd --version, dd --help e man dd no sistema de destino. A preparação cria uma área exclusiva e entradas descartáveis; execute-a no mesmo terminal e pare diante de erro. As práticas gravam apenas em arquivos dessa área. Consultas de dispositivos são apresentadas separadamente e não executam uma restauração.

O que é o comando dd?

Por padrão, dd lê da entrada padrão e escreve na saída padrão. Os operandos principais têm a forma nome=valor, sem espaços ao redor de =. A saída indicada por of= pode ser truncada ao abrir, antes mesmo de terminar a leitura. conv=notrunc evita esse truncamento, mas ainda permite sobrescrever os bytes atingidos. O manual GNU de dd detalha esses efeitos.

Sintaxe básica

dd [operando]...

operando é um marcador. Para caminhos com espaços, use if="arquivo de entrada" e of="arquivo de saída", mantendo cada operando como um argumento. Um nome como -entrada fica dentro de if=-entrada, em vez de virar uma opção isolada. Opções como --help têm outra finalidade; dd não usa -if ou -of.

Uso básico do dd

Copiar um arquivo para outro

A preparação cria source.img com os 16 bytes 0123456789ABCDEF e uma cópia independente para controle. bs=4K permite blocos de até 4.096 bytes, mas o arquivo é menor: o último bloco pode ser parcial. conv=excl exige criar uma saída nova e recusa copy.img se ela já existir. Para cópias comuns de arquivos e diretórios, veja também cp.

dd_start=$PWD
dd_demo=$(mktemp -d -p "$PWD" 'dd-demo.XXXXXXXX') &&
cd -- "$dd_demo" &&
printf '0123456789ABCDEF' > source.img &&
cp -- source.img source.backup &&
printf 'controle intacto\n' > sentinel.txt &&
dd if=source.img of=copy.img bs=4K conv=excl status=progress

Criar um arquivo de tamanho fixo preenchido com zeros

/dev/zero fornece bytes zero indefinidamente; count limita a leitura. Aqui, dois blocos de 1M produzem 2.097.152 bytes, e stat deve mostrar 2097152 test.bin. O GNU interpreta M como 1.048.576 bytes e MB como 1.000.000. Esta chamada escreve dados zero, ao contrário de apenas mudar o comprimento com truncate; o espaço físico final ainda depende de compressão, desduplicação e outras características do armazenamento. Não trate a escrita de zeros como reserva universal de espaço ou apagamento seguro.

cd -- "$dd_demo" &&
dd if=/dev/zero of=test.bin bs=1M count=2 conv=excl status=progress &&
stat -c '%s %n' -- test.bin

Entender a criação de uma imagem

Uma imagem captura os bytes lidos da origem; se ela estiver mudando durante a cópia, o resultado pode misturar estados incompatíveis. Um dispositivo desmontado, um snapshot (instantâneo) consistente ou um backup coordenado com a aplicação pode ser necessário. Para praticar a direção de leitura e escrita, o exemplo abaixo cria disk-image-demo.img a partir do arquivo controlado de 16 bytes. conv=fsync solicita sincronizar dados e metadados da saída antes de terminar; não valida a consistência interna da imagem.

cd -- "$dd_demo" &&
dd if=source.img of=disk-image-demo.img bs=4K conv=excl,fsync status=progress

Comparar o resultado de uma cópia pequena

Esta prática independente escreve três bytes em source.bin, cria uma saída nova e compara os dois arquivos. A mensagem só aparece se a criação, a cópia e a comparação tiverem sucesso. Isso verifica igualdade no momento da leitura; não autentica a origem, não testa recuperação após falta de energia e não verifica uma estrutura de partições.

cd -- "$dd_demo" &&
printf 'ABC' > source.bin &&
dd if=source.bin of=copy.bin bs=1 conv=excl status=none &&
cmp -s -- source.bin copy.bin &&
printf '%s\n' 'Bytes iguais.'

O resultado esperado é Bytes iguais.. status=none suprime mensagens informativas e avisos de transferência, mas erros ainda são exibidos e precisam ser tratados. Uma cópia parcial ou uma falha não é desfeita automaticamente. Preserve a entrada e confira o resultado antes de usá-lo.

Principais operandos

Operando Significado e condição
if=ARQUIVO Escolher a entrada; sem este operando, usar a entrada padrão.
of=ARQUIVO Escolher a saída; pode truncar ou sobrescrever um destino existente.
bs=TAMANHO Definir os tamanhos de entrada e saída juntos; prevalece sobre ibs e obs.
count=N Limitar blocos de entrada. Leituras curtas exigem atenção; fullblock acumula leituras para contar blocos completos.
skip=N Avançar N blocos de entrada, na unidade de ibs.
seek=N Avançar N blocos de saída, na unidade de obs, antes de gravar.
status=progress Mostrar estatísticas de transferência na saída de erro padrão; não é uma porcentagem garantida nem prova de persistência.
conv=noerror,sync Continuar após erros de leitura e preencher blocos curtos. Pode inserir zeros no resultado; não recupera bytes ilegíveis.
conv=fsync Solicitar sincronização dos dados e metadados da saída antes de terminar, inclusive após erros de escrita.
iflag=fullblock Acumular leituras curtas até completar um bloco ou atingir o fim da entrada; útil em pipes, os encadeamentos entre comandos.

ibs é o tamanho do bloco de entrada e obs o de saída; ambos têm padrão de 512 bytes, enquanto bs define os dois juntos. conv=sync preenche blocos de entrada com bytes zero, salvo conversões de registros que usam espaços. Isso é diferente de conv=fsync, que trata de sincronização, e de oflag=sync, que solicita escrita sincronizada a cada operação. status=progress atualiza estatísticas periodicamente: uma prática muito curta pode terminar antes de mostrar atualizações intermediárias. Evite repetir operandos como bs ou count com valores diferentes.

Exemplos práticos

Conferir um dispositivo e ensaiar uma restauração

No Linux, consulte lsblk -o NAME,SIZE,MODEL,SERIAL,FSTYPE,MOUNTPOINTS e findmnt para examinar dispositivos e montagens. São consultas de leitura, não autorização nem prova isolada de que um alvo está livre. Em uma restauração real, confirme modelo, número de série, capacidade, partições, todas as montagens e o formato da imagem; nomes de dispositivos podem mudar após reiniciar ou reconectar. A gravação no dispositivo de saída substitui seus dados e exige um procedimento apropriado para que ele não esteja em uso. O ensaio abaixo faz essa direção de cópia em outro arquivo regular.

cd -- "$dd_demo" &&
dd if=disk-image-demo.img of=restore-demo.img bs=4K conv=excl,fsync status=progress &&
printf '................' > patch-demo.bin &&
dd if=source.img of=patch-demo.bin bs=4 skip=1 seek=2 count=1 conv=notrunc status=none &&
od -An -tc -- patch-demo.bin

No ensaio, restore-demo.img deve conter os mesmos 16 bytes da imagem preparada. A segunda parte demonstra seek em um arquivo separado: blocos de quatro bytes, skip=1, seek=2 e count=1 escrevem 4567 no deslocamento oito de patch-demo.bin. Com conv=notrunc, os pontos antes e depois permanecem, resultando em ........4567..... Isso ainda é uma alteração destrutiva da região atingida, sem desfazer automático.

Extrair um intervalo de uma imagem

O exemplo usa blocos de quatro bytes: skip=1 começa no deslocamento quatro e count=2 copia até oito bytes, resultando em 456789AB. iflag=fullblock evita que leituras curtas sejam contadas como blocos completos, mas não cria dados além do fim da entrada. Para contagens em bytes, o GNU Coreutils 9.1 introduziu o sufixo B em skip, seek e count, como skip=4B count=8B. Confira a versão instalada; com bs=1, os blocos de um byte também permitem deslocamentos exatos, com possível custo de desempenho em arquivos grandes.

cd -- "$dd_demo" &&
dd if=source.img of=segment.bin bs=4 skip=1 count=2 iflag=fullblock conv=excl status=none &&
od -An -tc -- segment.bin

Verificar a saída copiada

Salve o script completo como verify-dd.sh e execute bash verify-dd.sh "$dd_demo/source.img" "$dd_demo/copy.img". Ele requer Bash, cmp, GNU stat e sha256sum. Recebe dois arquivos regulares, recusa links simbólicos finais e dois nomes do mesmo arquivo, compara os bytes e mostra tamanho e resumo SHA-256, um código calculado a partir do conteúdo. A mensagem esperada é Bytes conferidos.; uso incorreto retorna 2, e diferença ou falha retorna 1.

#!/usr/bin/env bash
if (( $# != 2 )); then
  printf '%s\n' 'Uso: bash verify-dd.sh ORIGEM COPIA' >&2
  exit 2
fi
if [[ ! -f $1 || -L $1 || ! -f $2 || -L $2 || $1 -ef $2 ]]; then
  printf '%s\n' 'Use dois arquivos regulares distintos, sem links simbólicos finais.' >&2
  exit 1
fi
cmp -s -- "$1" "$2" || { printf '%s\n' 'Diferença ou falha de leitura.' >&2; exit 1; }
stat -c '%s %n' -- "$1" "$2" || exit 1
sha256sum -- "$1" "$2" || exit 1
printf '%s\n' 'Bytes conferidos.'

Nos arquivos desta prática, os tamanhos devem ser 16 e os resumos SHA-256 devem coincidir. O script só lê e não altera os arquivos; mantenha-os estáveis durante a comparação. O resultado confirma bytes atuais, não todos os metadados, autenticidade de uma imagem ou durabilidade após perda de energia. conv=fsync deve terminar sem erro quando usado, mas a garantia de persistência também depende do sistema e do dispositivo. Uma restauração em um dispositivo maior precisa comparar o intervalo gravado, não presumir que o dispositivo inteiro terá o mesmo hash da imagem menor.

Comparar dd e outras ferramentas

Comando ou método Função principal Quando usar
dd Cópia e conversão orientada a blocos Imagens e intervalos controlados por blocos ou bytes
cp Cópia de arquivos ao nível do sistema de arquivos Cópias comuns de arquivos e árvores de diretórios
rsync Sincronização incremental e remota Atualizações repetidas, inclusive em destinos remotos
GNU ddrescue Tentar novamente e mapear leituras de mídia danificada Recuperar primeiro regiões legíveis e retomar com um mapa do trabalho

Cuidados importantes

Trocar if e of pode destruir a origem

Confira a direção imediatamente antes de executar. conv=excl recusa um caminho de saída já existente, inclusive um dispositivo existente; não remova essa proteção automaticamente só porque uma tentativa de gravação falhou. Uma operação real em dispositivo exige a identificação do alvo e um procedimento próprio. Não use origem e destino como dois links para os mesmos dados. Ao terminar, volte com cd -- "$dd_start"; os arquivos restantes continuam disponíveis para inspeção e remoção individual.

Um tamanho de bloco maior nem sempre é melhor

O resultado depende do dispositivo, do sistema e da carga. Blocos grandes demais aumentam o uso de memória e podem dificultar a recuperação de regiões pequenas com erro. Em pipes, leituras curtas e o uso de fullblock também importam para interpretar count. Não transforme a velocidade mostrada com caches em uma garantia de desempenho de qualquer disco.

Use uma ferramenta específica de recuperação para mídias com falha

noerror continua após erros de leitura; sync preenche blocos, mas nenhum deles reconstrói o conteúdo ilegível. O manual oficial do GNU ddrescue descreve a estratégia de recuperar regiões boas primeiro e usar um mapfile, um arquivo que registra regiões já processadas e permite retomar o trabalho. Uma mídia com falha pode piorar durante leituras: evite reparar o sistema de arquivos diretamente nela e avalie a importância dos dados antes de insistir. GNU ddrescue é uma ferramenta diferente de dd e de programas com nomes parecidos.

Perguntas frequentes

O que significam if e of?

if seleciona a entrada para leitura e of a saída para escrita. Sem eles, o GNU usa entrada e saída padrão. Um of incorreto pode truncar um arquivo ou sobrescrever um dispositivo; confirme a direção e o alvo.

Como eu exibo o progresso?

Use status=progress no GNU dd. Ele mostra estatísticas de transferência na saída de erro padrão, que podem ser adiadas durante certas operações e não equivalem a uma porcentagem conhecida nem à verificação final dos bytes. Em cópias pequenas, podem aparecer apenas as estatísticas finais.

Uma imagem de disco inteira deve ser gravada em um caminho de partição?

Siga as instruções do fornecedor da imagem. Uma imagem que inclui a tabela de partições normalmente corresponde ao dispositivo inteiro; uma imagem de uma única partição tem outro escopo. Não decida apenas pela extensão do arquivo. Confira formato, tamanho, integridade fornecida pela origem, identidade do destino e ausência de uso antes de planejar a gravação.

O dd pode recuperar um disco com erros de leitura?

Ele pode copiar trechos legíveis, mas conv=noerror,sync não substitui uma estratégia de recuperação com tentativas controladas e mapa de progresso. O GNU ddrescue oferece esses recursos. Evite trabalhar na única cópia de dados importantes ou executar reparos diretamente na mídia com erros.