Comando cp: copiando pastas de arquivo para * nix corretamente



Neste artigo, serão reveladas algumas coisas não óbvias relacionadas ao uso de curingas ao copiar, o comportamento ambíguo do comando cp ao copiar, bem como maneiras de copiar corretamente um grande número de arquivos sem omissões e falhas.

Suponha que precisamos copiar tudo da pasta / source para a pasta / target.

A primeira coisa que vem à mente é:

 cp /source/* /target 

Corrija imediatamente este comando para:

 cp -a /source/* /target 

A opção -a adiciona uma cópia de todos os atributos, direitos e adiciona recursão. Quando a reprodução exata dos direitos não é necessária, a opção -r é suficiente.

Após a cópia, descobrimos que nem todos os arquivos foram copiados - os arquivos iniciados a partir de um ponto como foram ignorados:

.profile
.local
.mc

e coisas assim.

Por que isso aconteceu?

Como os curingas processam o shell ( bash em um caso típico). Por padrão, o bash ignora todos os arquivos que começam com pontos, pois os trata como ocultos. Para evitar esse comportamento, precisamos alterar o comportamento do bash usando o comando:

 shopt -s dotglob 

Para salvar essa alteração no comportamento após uma reinicialização, você pode criar o arquivo wildcard.sh com este comando na pasta /etc/profile.d (sua distribuição pode ter uma pasta diferente).

E se não houver arquivos no diretório de origem, o shell não poderá substituir nada pelo asterisco, e a cópia também falhará. Contra essa situação, existem nullglob e nullglob . Precisamos definir failglob , o que impedirá a execução do comando. nullglob não funcionará, porque converte uma sequência com caracteres curinga que não encontraram correspondências em uma sequência vazia (de comprimento zero), o que causará um erro no cp .

No entanto, se houver milhares de arquivos e mais na pasta, a abordagem usando curingas deve ser abandonada por completo. O fato é que o bash expande curingas em uma linha de comando muito longa, como:

 cp -a /souce/a /source/b /source/c …… /target 

Há uma limitação no comprimento da linha de comando que podemos descobrir usando o comando:

 getconf ARG_MAX 

Obtenha o comprimento máximo da linha de comando em bytes:

 2097152 

Ou:

 xargs --show-limits 

Temos algo como:

 …. Maximum length of command we could actually use: 2089314 …. 

Então, vamos fazer sem curingas.

Vamos escrever

 cp -a /source /target 

E aqui encontraremos a ambiguidade do comportamento da cp . Se a pasta / target não existir, obteremos o que precisamos.

No entanto, se a pasta de destino existir, os arquivos serão copiados para a pasta / target / source.

Nem sempre podemos excluir a pasta / target antecipadamente, pois ela pode conter os arquivos que precisamos e nosso objetivo, por exemplo, é adicionar arquivos ao / target com arquivos de / source.

Se as pastas de origem e destino fossem nomeadas da mesma maneira, por exemplo, copiaríamos de / source para / home / source, então poderíamos usar o comando:

 cp -a /source /home 

E depois de copiar os arquivos em / home / source, seriam os arquivos complementados de / source.

Essa é a tarefa lógica: podemos adicionar arquivos ao diretório de destino, se as pastas tiverem o mesmo nome, mas se diferirem, a pasta de origem será colocada dentro do receptor. Como copiar arquivos de / source para / target usando cp sem curingas?

Para contornar essa limitação prejudicial, usamos uma solução não óbvia:

 cp -a /source/. /target 

Quem conhece bem o DOS e o Linux já entendeu tudo: dentro de cada pasta existem 2 pastas invisíveis "." e "..", que são links de pseudo-pastas para os diretórios atuais e superiores.

  • Ao copiar, o cp verifica a existência e tenta criar / target /.
  • Esse diretório existe e é / target
  • Arquivos de / source copiados para / target corretamente.

Então, penduramos em uma moldura arrojada em nossa memória ou na parede:

 cp -a /source/. /target 

O comportamento deste comando é inequívoco. Tudo funcionará sem erros, independentemente de você ter um milhão de arquivos ou nenhum.

Conclusões


Se você deseja copiar todos os arquivos de uma pasta para outra, não usamos curingas; em vez deles, é melhor usar o cp em combinação com um ponto no final da pasta de origem. Isso copiará todos os arquivos, incluindo os ocultos, e não falhará com milhões de arquivos ou a ausência completa de arquivos.

Posfácio


O vmspike sugeriu uma variante semelhante do comando:

 cp -a -T /source /target 

Oz_Alex
 cp -aT /source /target 

ATENÇÃO: o caso da letra T importante. Se você confundir, recebe o lixo completo: a direção da cópia muda.

Agradecimentos:

  • Empresa RUVDS.COM por seu apoio e pela oportunidade de publicar em seu blog no Habr.
  • Por imagem TripletConcept . A imagem é muito grande e detalhada. Você pode abri-la em uma janela separada.

PS Direct erros que você percebe no PM. Eu aumento o carma por isso.



Source: https://habr.com/ru/post/pt471092/


All Articles