Linux / Comando cp: copiar arquivos, diretórios e atributos

cp copia arquivos; -R também copia árvores de diretórios, e -a tenta preservar sua estrutura e seus atributos. Antes de executar, confira se o destino já existe: ele pode ser sobrescrito ou receber o nome do arquivo de origem dentro de uma pasta. Para uma cópia importante, confirme o status e compare o conteúdo, não apenas a existência do destino.

Os exemplos usam GNU Coreutils e Bash. Confira cp --version, cp --help e man cp no destino, pois opções e status de saída variam entre versões e sistemas. Prepare a área temporária antes dos exemplos seguintes; a prática não precisa escrever em /etc ou em uma pasta real de backup.

O que é o comando cp?

Ao criar um arquivo regular novo, cp normalmente produz uma cópia com inode próprio, a estrutura que identifica o arquivo no sistema de arquivos. Alterar o conteúdo dessa cópia não altera logicamente o original. Isso não implica duplicar imediatamente todos os blocos físicos: uma cópia com reflink pode compartilhar blocos até uma gravação. Ao sobrescrever um arquivo existente, não presuma que o inode do destino será substituído.

Sintaxe básica

cp [opções] [-T] origem destino
cp [opções] origem ... diretório
cp [opções] -t diretório origem ...

Coloque caminhos com espaços entre aspas e use -- no GNU para encerrar as opções antes dos nomes. -t exige uma pasta de destino; -T impede que o último argumento seja reinterpretado como pasta onde colocar o nome da origem. Essas opções não são combinadas entre si.

Uso básico do cp

Copiar um arquivo para um novo nome

Execute o bloco completo no mesmo terminal Bash usado pelos exemplos seguintes. Ele guarda a pasta inicial, cria uma área exclusiva e prepara arquivos com conteúdo conhecido. Os passos ligados por && só continuam após sucesso; pare se a preparação falhar. No fim, report-backup.txt será a cópia de report.txt, ambos dentro da prática.

cp_start=$PWD
cp_demo=$(mktemp -d "${TMPDIR:-/tmp}/cp-demo.XXXXXX") &&
cd -- "$cp_demo" &&
mkdir -p -- public src/sub app/sub backup source/sub &&
printf '%s\n' 'Relatório de teste.' > report.txt &&
printf '%s\n' '<p>Exemplo</p>' > index.html &&
printf '%s\n' 'p { color: navy; }' > style.css &&
printf '%s\n' 'arquivo da origem' > src/sub/file.txt &&
printf '%s\n' 'enabled=true' > app/sub/settings.ini &&
printf '%s\n' 'EXAMPLE=1' > app/.env &&
printf '%s\n' 'configuração nova' > config.ini &&
printf '%s\n' 'configuração antiga' > backup/config.ini &&
printf '%s\n' 'conf nova' > alpha.conf &&
printf '%s\n' 'conf antiga' > backup/alpha.conf &&
printf '%s\n' 'dados de exemplo' > source/sub/data.txt &&
printf '%s\n' 'item oculto' > source/.hidden &&
cp -- report.txt report-backup.txt

Copiar vários arquivos para um diretório

A preparação criou public. O comando abaixo coloca os dois arquivos nela, nos caminhos public/index.html e public/style.css. O equivalente com destino explícito é cp -t public -- index.html style.css. O cp não cria automaticamente uma pasta de destino que esteja faltando.

cp -- index.html style.css public/

Copiar uma árvore de diretórios

Na área nova, src-copy e app-backup ainda não existem. As cópias terão, respectivamente, src-copy/sub/file.txt e app-backup/sub/settings.ini. -R faz a travessia; -a também tenta preservar links e atributos suportados. Pare e examine qualquer diagnóstico de falha antes de tratar a cópia como concluída.

cp -R -- src src-copy &&
cp -a -- app app-backup

Comparar os bytes copiados

Crie um arquivo pequeno, copie-o e só exiba a confirmação se cada etapa funcionar. cmp -s compara os bytes sem imprimir uma diferença detalhada:

printf 'demo\n' > original.txt &&
cp -- original.txt copy.txt &&
cmp -s -- original.txt copy.txt &&
printf '%s\n' 'Os bytes da cópia são iguais.'

A confirmação esperada é Os bytes da cópia são iguais. Um cmp bem-sucedido não comprova dono, permissões, horários ou atributos estendidos iguais. Consulte também o guia de stat quando esses metadados fizerem parte do requisito. Se a origem estiver sendo alterada ao mesmo tempo, duas consultas não garantem um estado consistente.

Opções principais

Opção Propósito
-R, -r Copiar diretórios recursivamente; prefira -R e confira os links ao transportar para outro sistema.
-a Recorrer e tentar preservar links, horários e outros atributos.
-p Tentar preservar modo, dono/grupo e horários de acesso/modificação.
-i Pedir confirmação antes de sobrescrever um arquivo.
-n Pular arquivos existentes; opção desaconselhada na documentação GNU atual por diferenças de status entre plataformas.
-u Pular arquivos não diretórios quando o destino tem mtime igual ou mais recente, nas condições documentadas.
-T Usar o último argumento como destino exato, sem acrescentar o nome da origem.
-t DIR Usar a pasta especificada como destino das origens.
--reflink[=WHEN] Controlar cópia com blocos compartilhados quando houver suporte.

O -u comum compara o horário de modificação, mtime; ele não calcula um hash para decidir se o conteúdo mudou. Em versões atuais, --update=none mantém arquivos existentes sem falhar por pulá-los, enquanto --update=none-fail também diagnostica e retorna falha nesse caso. Este último foi introduzido no GNU Coreutils 9.5, mas essa versão tinha um erro que fazia cp rejeitar o argumento none-fail; o erro foi corrigido no 9.6. Para usar esse modo em cp, prefira 9.6 ou posterior, ou confirme que a distribuição aplicou a correção. As notas oficiais do GNU Coreutils 9.5 também registram que o status de -n mudou em versões 9.x. Verifique o suporte instalado e não interprete status 0 como prova de que todos os arquivos foram copiados.

Exemplos práticos

Controlar a sobrescrita

A preparação colocou versões diferentes de config.ini e alpha.conf em backup. Execute as linhas separadamente: na primeira, -i pergunta se deve substituir a configuração. Na segunda, -n mantém backup/alpha.conf existente. Esse exemplo ajuda a interpretar comandos antigos; para automação nova, avalie os modos --update acima e confira o resultado. O caractere * é expandido pelo Bash, e nessa prática corresponde a alpha.conf.

cp -iv -- config.ini backup/
cp -nv -- *.conf backup/

Tentar preservar atributos

Execute as duas linhas separadamente dentro da área preparada. -a equivale, em linhas gerais, a preservar links, recorrer e pedir todos os atributos, com diagnósticos reduzidos. ACL significa lista de controle de acesso; xattrs são atributos estendidos, e SELinux (Security-Enhanced Linux) acrescenta rótulos de segurança. Dono/grupo, ACL, xattrs, horários e rótulos dependem das permissões e dos sistemas de arquivos. Algumas falhas de preservação de xattrs ou contexto SELinux não mudam o status de -a; ausência de erro não prova preservação integral.

cp -a -- app app-snapshot
cp -a -- source destination

Distinguir links de origem e de destino

Sem recursão, uma origem que é link simbólico normalmente tem seu destino seguido. Com -R, o GNU normalmente preserva os links encontrados como links; -a também pede essa preservação. -L manda seguir os links de origem e -P manda copiá-los como links. Um link relativo preservado guarda o mesmo texto, que pode passar a apontar para outra localização na nova árvore.

As opções de links da origem não são uma regra para o destino: ao copiar para um link que aponta para um arquivo regular existente, o GNU pode alterar o arquivo apontado. Um link de destino sem alvo é recusado por padrão, com condições especiais documentadas como POSIXLY_CORRECT. Confira ambos os caminhos; o guia de readlink ajuda a ler o texto do link. Esses detalhes estão no manual GNU de cp.

Verificar cópias importantes

Salve este script completo como copy-verify.sh e execute bash copy-verify.sh "$cp_demo/report.txt" "$cp_demo/verified-report.txt". Ele requer Bash, GNU cp, cmp e sha256sum. Recebe um arquivo regular de origem e um caminho de destino exato; pode sobrescrever um arquivo de destino existente. Uso incorreto retorna 2, e falha de cópia, comparação ou hash retorna 1. Ao funcionar, as duas linhas de hash têm o mesmo resumo SHA-256 (Secure Hash Algorithm de 256 bits), com nomes diferentes.

#!/usr/bin/env bash
if [ "$#" -ne 2 ]; then
  printf '%s\n' 'Uso: bash copy-verify.sh ORIGEM DESTINO' >&2
  exit 2
fi
if [ ! -f "$1" ]; then
  printf '%s\n' 'A origem deve ser um arquivo regular acessível.' >&2
  exit 1
fi
cp -T -- "$1" "$2" || exit 1
if ! cmp -s -- "$1" "$2"; then
  printf '%s\n' 'Os bytes não coincidem ou a comparação falhou.' >&2
  exit 1
fi
sha256sum -- "$1" "$2" || exit 1

Para comparar a árvore preparada em src-copy, use diff -qr -- src src-copy: sem diferenças, não há saída e o status é 0; diferenças retornam 1 e erros retornam um valor maior. Essa comparação e o script verificam conteúdo, não todos os metadados ou a capacidade de restaurar um serviço. Dados em alteração podem exigir um snapshot, uma captura consistente do sistema de arquivos, ou o procedimento de backup da aplicação.

Comparar cp e comandos relacionados

Comando ou método Função principal Quando usar
cp Cópia de arquivos e diretórios locais Fazer cópias locais diretas
mv Mover ou renomear caminhos Mover ou renomear, sem manter o caminho de origem
rsync Sincronização incremental e remota Sincronizar repetidamente ou transferir por rede
install Copiar enquanto define atributos Copiar para instalação com atributos definidos

Cuidados importantes

O tipo de destino altera o resultado

Se src-copy já existir como diretório, repetir cp -R src src-copy pode criar src-copy/src. cp -RT -- src destino trata destino como a raiz exata da cópia, mas pode mesclar e sobrescrever entradas já existentes: -T não é proteção contra sobrescrita nem apaga itens extras do destino. Para copiar um arquivo para uma pasta, use -t ou um destino de pasta explícito.

O modo de arquivamento não é um sistema de backup completo

Uma cópia não congela arquivos abertos, bancos de dados ativos ou uma árvore que muda durante a leitura. Atributos não suportados e falhas parciais também limitam o resultado. Planeje uma cópia consistente e um teste de restauração para o serviço, em vez de tratar -a como sistema completo de backup.

Curingas do shell podem omitir entradas ocultas

No Bash com as opções padrão, source/* não inclui nomes iniciados por ponto. Para copiar o conteúdo da pasta, incluindo os ocultos, uma forma GNU é cp -a -- source/. destino/, após verificar o destino e a política de sobrescrita. Uma barra ao final de source/ sozinha não transforma o comando em uma regra idêntica à de outras ferramentas como rsync.

Reflink significa compartilhar blocos de dados com copy-on-write, que grava novos blocos quando uma das cópias é modificada. --reflink=auto permite voltar à cópia comum se o recurso não existir; --reflink=always exige o recurso e pode falhar, e --reflink=never o desativa. O suporte não garante uma cópia em outro dispositivo. Ao terminar a prática, volte à pasta inicial com cd -- "$cp_start"; os arquivos de teste ficam disponíveis para inspeção.

Perguntas frequentes

Devo usar -R ou -a para um diretório?

Use -R para recursão básica e -a quando for importante preservar links e metadados suportados.

Como posso evitar sobrescrever arquivos existentes?

O -n aparece em comandos existentes, mas a documentação GNU atual o desaconselha por diferenças de status. Avalie --update=none ou --update=none-fail, conforme o resultado desejado e o suporte instalado. No cp, este último foi introduzido em 9.5, mas exige a correção incluída no 9.6 ou aplicada pela distribuição.

Por que um diretório copiado aparece em uma profundidade diferente da esperada?

Quando o destino existe como pasta, o nome da origem pode ser acrescentado. -T usa a raiz de destino exata e -t exige uma pasta receptora; essas opções não impedem por si só sobrescritas ou mesclagens.

Como posso verificar uma cópia?

Compare os hashes dos arquivos e use ferramentas como diff -qr para árvores de diretórios. Um backup real também precisa de um teste de restauração.

Documentação oficial