dd (Português)

From ArchWiki

Status de tradução: Esse artigo é uma tradução de dd. Data da última tradução: 2020-04-09. Você pode ajudar a sincronizar a tradução, se houver alterações na versão em inglês.

dd é um dos utilitários principais cujo propósito primário é converter e copiar um arquivo.

Similarmente ao cp, o dd faz, por padrão, uma cópia bit a bit do arquivo, mas com recursos de controle de fluxo de E/S de nível inferior.

Para mais informações, consulte dd(1) ou a documentação completa.

Dica: Por padrão, dd não produz nada até que a tarefa seja finalizada. Para monitorar o progresso da operação, adicione a opção status=progress ao comando.
Atenção: Deve-se ter extrema cautela ao usar o dd, como em qualquer comando desse tipo, ele pode destruir dados irreversivelmente.

Instalação

dd é parte do GNU coreutils. Para outros utilitários no pacote, por favor, confira Utilitários principais.

Clonagem e restauração de disco

O comando dd é uma ferramenta simples, mas versátil e poderosa. Ele pode ser usado para copiar da origem para o destino, bloco por bloco, independentemente de seus tipos de sistema de arquivos ou sistemas operacionais. Um método conveniente é usar dd em um ambiente live, como em um Live CD.

Atenção: Assim como com qualquer comando desse tipo, você deve ter muita cautela ao usá-lo; pode destruir dados. Lembre-se da ordem do arquivo de entrada (if=) e do arquivo de saída (of=) e não os inverta! Certifique-se sempre de que a unidade ou partição de destino (of=) seja de tamanho igual ou maior que a origem (if=).

Clonando uma partição

Do disco físico /dev/sda, partição 1, para disco físico /dev/sdb, partição 1:

# dd if=/dev/sda1 of=/dev/sdb1 bs=64K conv=noerror,sync status=progress
Nota: Tenha cuidado se a partição de saída of (sdb1 no exemplo) não existir, dd criará um arquivo com este nome e começará a encher seu sistema de arquivos raiz.

Clonando todo um disco rígido

Do disco físico /dev/sda para um disco físico /dev/sdb:

# dd if=/dev/sda of=/dev/sdb bs=64K conv=noerror,sync status=progress

Isso irá clonar a unidade inteira, incluindo o MBR (e, portanto, o gerenciador de boot), todas as partições, UUIDs e dados.

  • bs= define o tamanho do bloco. O padrão é 512 bytes, que é o tamanho de bloco "clássico" para discos rígidos desde o início dos anos 80, mas não é o mais conveniente. Use um valor maior, 64K ou 128K. Além disso, leia o aviso abaixo, porque há mais do que apenas "tamanhos de bloco" - também influencia a maneira como os erros de leitura se propagam. Veja [1] e [2] para detalhes e para descobrir o melhor valor de bs para o seu caso de uso.
  • noerror instrui o dd a continuar a operação, ignorando todos os erros de leitura. O comportamento padrão para dd é parar em qualquer erro.
  • sync preenche os blocos de entrada com zeros se houver algum erro de leitura, para que os deslocamentos de dados permaneçam em sincronia.
  • status=progress mostra estatísticas de transferência periódicas que podem ser usadas para estimar quando a operação pode estar completa.
Nota: O tamanho do bloco que você especifica influencia como os erros de leitura são manipulados. Leia abaixo. Para recuperação de dados, use ddrescue.

O utilitário dd tecnicamente possui um "tamanho de bloco de entrada" (IBS) e um "tamanho de bloco de saída" (OBS). Quando você define bs, você efetivamente define IBS e OBS. Normalmente, se o tamanho do bloco for, digamos, 1 MiB, o dd lerá 1024×1024 bytes e gravará essa mesma quantidade de bytes. Mas se ocorrer um erro de leitura, as coisas vão dar errado. Muitas pessoas parecem pensar que o dd irá "preencher erros de leitura com zeros" se você usar as opções noerror, sync, mas isto não é o que acontece. O dd irá, segundo a documentação, preencher o OBS para o tamanho IBS depois de completar sua leitura, o que significa adicionar zeros no fim do bloco. Isso significa, para um disco, que efetivamente todo o 1 MiB seria confuso por causa de um único erro de leitura de 512 bytes no início da leitura: 12ERROR89 se tornaria 128900000 em vez de 120000089.

Se você está certo de que o seu disco não contém erros, você pode continuar usando um tamanho de bloco maior, o que aumentará a velocidade da cópia várias vezes. Por exemplo, a alteração de bs de 512 para 64K alterou a velocidade de cópia de 35 MB/s para 120 MB/s em um sistema Celeron de 2,7 GHz. Mas lembre-se de que os erros de leitura no disco de origem terminarão como erros de bloco no disco de destino, ou seja, um único erro de leitura de 512 bytes estragará todo o bloco de saída de 64 KiB.

Dica: Se você quiser ver o progresso de dd, use a opção status=progress. Veja dd(1) para detalhes.
Nota:
  • Para obter UUIDs únicos de um sistema de arquivos ext2/3/4, use tune2fs/dev/sdXY -U random em cada partição. Para partições de swap, use mkswap/dev/sdXY.
  • Mudanças na tabela de partição com o dd não são registradas pelo kernel. Para notificar as alterações sem reinicializar, use um utilitário como partprobe (parte do GNU Parted).

Fazer backup da tabela de partição

Veja fdisk#Backup and restore partition table ou gdisk#Backup and restore partition table.

Criar imagem de disco

Inicialize a partir de uma mídia ao vivo e certifique-se de que nenhuma partição seja montada a partir do disco rígido de origem.

Em seguida, monte o disco rígido externo e faça o backup da unidade:

# dd if=/dev/sda conv=sync,noerror bs=64K | gzip -c  > /caminho/para/backup.img.gz

Se necessário (por exemplo, quando os arquivos resultantes serão armazenados em um sistema de arquivos FAT32), divida a imagem do disco em vários volumes (veja também split(1)):

# dd if=/dev/sda conv=sync,noerror bs=64K | gzip -c | split -a3 -b2G - /caminho/para/backup.img.gz

Se não houver espaço em disco suficiente localmente, você poderá enviar a imagem por meio de ssh:

# dd if=/dev/sda conv=sync,noerror bs=64K | gzip -c | ssh usuario@local dd of=backup.img.gz

Finalmente, salve informações extras sobre a geometria da unidade necessária para interpretar a tabela de partição armazenada na imagem. O mais importante dos quais é o tamanho do cilindro.

# fdisk -l /dev/sda > /caminho/para/lista_fdisk.info
Nota: Você pode querer usar um tamanho de bloco (bs=) que seja igual à quantidade de cache no HD que você está fazendo backup. Por exemplo, bs=8192K funciona para um cache de 8 MiB. O 64 KiB mencionado neste artigo é melhor que o padrão bs=512 bytes, mas pode ser mais rápido se executado com um bs= maior.
Dica: O gzip só é capaz de compactar dados usando um único núcleo ("core") de CPU, o que leva a um "throughput" de dados consideravelmente menor que as velocidades de gravação no armazenamento moderno. Para aproveitar a compactação com vários núcleos e criar uma imagem de disco mais rapidamente, pode-se instalar o pacote pigz e simplesmente substituir o comando gzip -c acima por pigz -c. Para discos grandes, isso pode economizar horas.

Restaurar o sistema

Para restaurar seu sistema:

# gunzip -c /caminho/para/backup.img.gz | dd of=/dev/sda

Quando a imagem tiver sido dividida com split, use o seguinte:

# cat /caminho/para/backup.img.gz* | gunzip -c | dd of=/dev/sda

Aplicação de patch em arquivo binário

Caso queira substituir a posição 0x123AB de um arquivo com a sequência hexadecimal FF C0 14, isso pode ser feito com a linha de comando:

# printf '\xff\xc0\x14' | dd seek=$((0x123AB)) conv=notrunc bs=1 of=/path/to/file

Fazer backup e restaurar MBR

Antes de fazer alterações em um disco, você pode querer fazer backup da tabela de partição e do esquema de partição da unidade. Você também pode usar um backup para copiar o mesmo layout de partição para várias unidades.

O MBR é armazenado nos primeiros 512 bytes do disco. Consiste em 4 partes:

  1. Os primeiros 440 bytes contêm o código de bootstrap (gerenciador de boot).
  2. Os próximos 6 bytes contêm a assinatura do disco.
  3. Os próximos 64 bytes contêm a tabela de partição (4 entradas de 16 bytes cada, uma entrada para cada partição primária).
  4. Os últimos 2 bytes contêm uma assinatura de inicialização.

Para salvar o MBR como arquivo_mbr.img:

# dd if=/dev/sdX of=/caminho/para/arquivo_mbr.img bs=512 count=1

Você também pode extrair o MBR de uma imagem completa do disco dd:

# dd if=/caminho/para/disco.img of=/caminho/para/arquivo_mbr.img bs=512 count=1

Para restaurar (cuidado, isso destrói a tabela de partição existente e, com ela, o acesso a todos os dados no disco):

# dd if=/caminho/para/arquivo_mbr.img of=/dev/sdX bs=512 count=1
Atenção: Restaurar o MBR com uma tabela de partição incompatível tornará seus dados ilegíveis e quase impossíveis de recuperar. Se você simplesmente precisar reinstalar o gerenciador de boot, consulte suas respectivas páginas, pois elos também empregam a região de compatibilidade do DOS: GRUB ou Syslinux.

Se você deseja restaurar apenas o gerenciador de boot, mas não as entradas da tabela de partição primária, basta restaurar os primeiros 440 bytes do MBR:

# dd if=/caminho/para/arquivo_mbr.img of=/dev/sdX bs=440 count=1

Para restaurar apenas a tabela de partição, você deve usar:

# dd if=/caminho/para/arquivo_mbr.img of=/dev/sdX bs=1 skip=446 count=64

Remover o gerenciador de boot

Para apagar o código de bootstrap do MBR (pode ser útil se você tiver que fazer uma reinstalação completa de outro sistema operacional) apenas os primeiros 440 bytes precisam ser zerados:

# dd if=/dev/zero of=/dev/sdX bs=440 count=1

Resolução de problemas

Leitura parcial

Arquivos criados com dd podem terminar com um tamanho menor do que o solicitado se o bloco completo de entrada não está disponível e a chamada de sistema read(2) retorna antes do esperado. Isto pode acontecer quando ler de um pipe(7) ou do /dev/random e não tem entropia o bastante[3], ou do /dev/urandom quando ler mais do que 32 MiB[4].

É possível, mas não garantido, que dd vai avisá-lo sobre o problema:

dd: warning: partial read (X bytes); suggest iflag=fullblock

A solução é fazer como o aviso recomenda e adicionar iflag=fullblock para o comando, Por exemplo:

$ dd if=/dev/random of=grande_segredo.img bs=1K count=1 iflag=fullblock
$ dd if=/dev/urandom of=grande_segredo.img bs=40M count=1 iflag=fullblock
Nota: É fortemente recomendado sempre adicionar a opção iflag=fullblock quando o arquivo de entrada é o /dev/random ou /dev/urandom.

Uma alternativa para /dev/urandom é especificar o tamanho do bloco menor que 32 MiB, com um maior número de copías. Por exemplo:

$ dd if=/dev/urandom of=grande_segredo.img bs=1M count=40

Quando ler de uma pipe, uma alternativa para iflag=fullblock é limitar bs para o valor constante PIPE_BUF, definido em /usr/include/linux/limits.h [5]. Por exemplo:

$ cat entrada.img | dd of=saida.img bs=4k count=100