Comando cp: copiando corretamente pastas com arquivos em *nix

Comando cp: copiando corretamente pastas com arquivos em *nix

Neste artigo, algumas questões inesperadas relacionadas ao uso de wildcards durante a cópia, o comportamento ambíguo do comando cp ao copiar, bem como maneiras de copiar corretamente um grande número de arquivos sem omissões ou erros.

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

A primeira coisa que vem à mente é:

cp /source/* /target

Vamos corrigir este comando para:

cp -a /source/* /target

Chave -a que adicionará a cópia de todos os atributos, permissões e incluirá recursão. Quando não é necessária a reprodução exata de permissões, basta a opção -r.

Após a cópia, descobrimos que nem todos os arquivos foram copiados – arquivos que começam com ponto, como:

.perfil
.local
.mc

e similares.

Por que isso aconteceu?

Porque os wildcards são processados pelo shell (bash normalmente). Por padrão, o bash ignora todos os arquivos que começam com ponto, tratando-os como ocultos. Para evitar esse comportamento, precisamos mudar a configuração bash usando o comando:

shopt -s dotglob

Para que essa mudança de comportamento seja mantida após a reinicialização, podemos criar um arquivo wildcard.sh com este comando na pasta /etc/profile.d (pode ser que em sua distribuição o caminho seja diferente).

E se não houver arquivos no diretório de origem, o shell não conseguirá substituir o asterisco por nada e a cópia também falhará. Para evitar essa situação, existem opções failglob e nullglob. Precisamos definir failglob, que impedirá a execução do comando. nullglob não serve, pois ela transforma as strings com wildcards que não encontraram correspondências em uma string vazia (de comprimento zero), o que causará cp um erro.

No entanto, se houver milhares de arquivos ou mais na pasta, é melhor desistir do uso de wildcards. O problema é que bash expande os wildcards em uma linha de comando muito longa, como:

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

Há um limite para o comprimento da linha de comando, que podemos descobrir usando o comando:

getconf ARG_MAX

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

2097152

Ou:

xargs --show-limits

Obteremos algo tipo:

….
Comprimento máximo do comando que realmente poderíamos usar: 2089314
….

Então, vamos tentar não usar wildcards.

Vamos apenas escrever

cp -a /source /target

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

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

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

Se as pastas de origem e destino tivessem o mesmo nome, por exemplo, estivéssemos copiando de /source para /home/source, poderíamos usar o comando:

cp -a /source /home

E após a cópia, os arquivos em /home/source teriam sido complementados com arquivos de /source.

Aqui está um enigma lógico: podemos complementar os arquivos no diretório de destino se as pastas tiverem o mesmo nome, mas se forem diferentes, a pasta de origem será colocada dentro da pasta de destino. Como copiar arquivos de /source para /target usando cp sem wildcards?

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

cp -a /source/. /target

Aqueles que estão bem familiarizados com DOS e Linux já entenderam tudo: dentro de cada pasta existem duas pastas invisíveis, "." e "..", que são pseudopastas referenciando o diretório atual e o diretório pai.

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

Portanto, mantenha isso bem guardado na sua memória ou na parede:

cp -a /source/. /target

Comportamento desse comando é claro. Tudo funcionará sem erros, independentemente de você ter milhões de arquivos ou nenhum.

Como resultado, obtemos um serviço de "monitoramento como serviço", automatizado na linha de produção de integração contínua. O desenvolvedor ou testador precisa apenas definir a lista de métricas em um arquivo JSON, e tudo o mais acontece automaticamente. Obtemos um controle de qualidade transparente dos lançamentos: todas as notificações sobre desempenho, consumo de recursos ou regressões arquitetônicas.

Se precisar copiar tudo arquivos de uma pasta para outra, não use wildcards; em vez disso, é melhor usar cp em combinação com um ponto no final da pasta de origem. Isso copiará todos os arquivos, incluindo ocultos, e não falhará com milhões de arquivos ou na ausência total de arquivos.

Epílogo

vmspike sugeriu uma versão de comando com resultado semelhante:

cp -a -T /source /target

Oz_Alex

cp -aT /source /target

CUIDADO: a capitalização importa. Se você errar, vai acabar com uma completa confusão: a direção da cópia mudará. T RUVDS.COM
Agradecimentos:

  • À empresa Sobre a imagem pelo apoio e pela oportunidade de publicação em seu blog no Habr.
  • . A imagem é muito grande e detalhada, pode ser aberta em uma nova janela. TripletConceptNeste artigo serão revelados.

P.S. Caso encontre erros, envie uma mensagem privada. Isso melhora minha karma.

Comando cp: copiando corretamente pastas com arquivos em *nix

Fonte: habr.com

Compre hospedagem confiável para sites com proteção contra DDoS, servidores VPS VDS 🔥 Compre hospedagem confiável para sites com proteção contra DDoS, servidores VPS VDS | ProHoster