it-swarm-pt.tech

Copiando recursivamente arquivos ocultos - Linux

Existe uma maneira fácil de copiar recursivamente todos os arquivos ocultos em um diretório para outro diretório? Gostaria de fazer backup apenas de todos os arquivos de configurações em um diretório inicial, não dos arquivos normais. Eu tentei:

cp -R .* directory

mas reconhece . e .. e copia recursivamente todos os arquivos não ocultos também. Existe uma maneira de fazer com que o cp ignore . e ..?

19
Zifre

Meu favorito para mover dirs em geral tem sido:

tar cvf - . | (cd /dest/dir; tar xvf -)

que eleva o diretório atual ao stdout e o canaliza para um subshell que primeiro o CD está no diretório de destino antes de remover o stdin. Simples, direto, extensível - considere o que acontece quando você substitui o () por um ssh para outra máquina. Ou, para responder sua pergunta, você pode fazer:

tar cvf - .* --exclude=\. --exclude=\.\. | (cd /dest/dir; tar xvf -)
15
pjz

Quase sempre que isso pode ser resolvido apenas com:

cp -R .[a-zA-Z0-9]* directory

É bastante incomum ter um arquivo oculto que não comece com um desses caracteres.

Outras correspondências de padrões estão disponíveis (.??*, .[^.]*) - veja os comentários

19
Alnitak

Você pode usar rsync.

rsync -a ./ /some/other/directory/

que copiará o conteúdo do diretório atual (incluindo arquivos de ponto, mas não incluindo ..)

11
Rory

Eu imploro, afaste-se da expansão simples do Shell na linha de comando cp - A expansão do shell tem todos os tipos de ahem canto "interessante" cases (recursão indesejada causada por. e .., espaços, itens não imprimíveis, hardlinks, links simbólicos etc.). Use find em vez disso (ele vem no pacote findutils, em caso você não o tenha instalado - o que seria estranho, todas as distribuições o instalam por padrão):

find -H /path/to/toplevel/dir/ -maxdepth 1 -name '.*' -a \( -type d -o -type f -o -type l \) -exec cp -a '{}' /path/to/destination/dir/ \;

Explicação passo a passo:

  • -H Fará com que find não siga os links simbólicos (exceto se o nome do diretório real de nível superior que você deu for um link simbólico; que será seguido.)
  • /path/to/toplevel/dir/ deve, obviamente, ser substituído por você pelo caminho do diretório que hospeda os arquivos de configuração e os diretórios que você deseja cópia de segurança.
  • -maxdepth 1 Impedirá que find desça recursivamente para qualquer diretório cujo nome comece com um ponto. Não precisamos recursar, cp fará isso por nós, apenas precisamos dos nomes nesse nível.
  • -name '.*' Diz a find que queremos todos os nomes que começam com um ponto. Isso não funcionará corretamente se a variável de ambiente POSIXLY_CORRECT Estiver definida, mas raramente (se houver). Essa é a primeira condição de correspondência especificada até o momento.
  • a \( ....... \) é um e seguido por uma condição mais complexa entre parênteses (usei ..... para substituí-lo, é explicado abaixo.) Precisamos escapar dos parênteses uma vez que eles serão (mal) interpretados pelo Shell, daí a barra invertida na frente deles,
  • -type d -o -type f -o -type l São três condições com um o entre elas. -type d Corresponde a diretórios, -type f Corresponde a arquivos regulares e -type l Corresponde a links simbólicos. Você pode selecionar o que deseja - por exemplo, se não desejar fazer backup dos diretórios de configurações, omita -type d (E o -o Logo atrás, obviamente).
  • -exec ..... \; Diz a find para executar um comando toda vez que uma correspondência é encontrada. O final do comando é marcado por um ponto e vírgula, do qual precisamos escapar novamente com uma barra invertida para evitar a interpretação do Shell. Dentro dessa linha de comando, você precisa usar {} Onde deseja que o nome da correspondência encontrada atualmente termine. Como os escudos também podem interpretar mal os chavetas, você deve colocá-los em apóstrofos, como em '{}'. O comando que queremos executar neste caso é cp -a '{}' /path/to/destination/dir/ (-A significa arquivo morto, que se repete em subdiretórios, copia links simbólicos como links e preserva permissões e atributos estendidos, e /path/to/destination/dir/ é obviamente o nome do diretório de destino - substitua-o.)

Portanto, em inglês simples, esta linha de comando find diz o seguinte:

Comece em/path/to/toplevel/dir /. Não desça em nenhum subdiretório. Encontre todos os diretórios, arquivos e links simbólicos cujo nome comece com um ponto. Para cada um dos encontrados, copie-o para/path/to/destination/dir/preservando a natureza, permissões e atributos estendidos.

10
Mihai Limbăşan

Eu sempre usei. ?? * para encontrar arquivos ocultos sem obter "." e "..". Pode faltar ".a" ou algo assim, mas nunca tenho um deles.

8
Paul Tomblin

Respostas muito melhores aqui; https://superuser.com/questions/61611/how-to-copy-with-cp-to-include-hidden-files-and-hidden-directories-and-their-con

Descreve, por exemplo, o uso de shopt para uma solução de bash nativa

0
Roel Van de Paar