
Neste artigo, algumas questões inesperadas relacionadas ao uso de 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/* /targetVamos 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 …… /targetHá um limite para o comprimento da linha de comando, que podemos descobrir usando o comando:
getconf ARG_MAXObteremos o comprimento máximo da linha de comando em bytes:
2097152Ou:
xargs --show-limitsObteremos 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 /homeE 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/. /targetAqueles 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
cpverifica 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
sugeriu uma versão de comando com resultado semelhante:
cp -a -T /source /target
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 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. Neste artigo serão revelados.
P.S. Caso encontre erros, envie uma mensagem privada. Isso melhora minha karma.
Fonte: habr.com
