Copiando um diretório pai em um subdiretório sem um loop infinito

3

Por motivos específicos do aplicativo, preciso copiar um diretório pai inteiro em um subdiretório. Por exemplo,

cp -r ../ tmp/

O problema é que ele fica preso em um loop infinito, recursivamente copiando o conteúdo do tmp / repetidamente.

Existem várias maneiras de contornar isso, como tarring o diretório e descompactá-lo no tmp, mas eu estou querendo saber se existem soluções particularmente elegantes / unixy.

(nota: estou usando o Apple OS / X).

    
por user1427661 27.05.2015 / 20:40

3 respostas

2

Se você iniciar a partir do diretório pai, poderá fazer isso com find e GNU cp . Supondo que o diretório em que você está atualmente (aquele que contém tmp ) seja chamado de folder e que tmp esteja vazio, você executaria

cd ..
find . -path ./folder/tmp -prune -o -type f -exec cp --parents -t folder/tmp {} +

Isso pede para encontrar listar tudo em . (que é seu antigo .. ), excluí-lo se corresponder a ./folder/tmp e, caso contrário, um arquivo passará para cp com a opção --parents (que diz cp para reconstruir a hierarquia de fontes).

Se tmp já tiver arquivos que também precisem ser copiados, a seguinte variante será um pouco menos Unix-y (já que usa moreutils ' sponge ), mas evita pular o conteúdo de tmp :

cd ..
find . -type f -print0 | sponge | xargs -0 cp --parents -t folder/tmp

Você pode evitar o uso de sponge salvando a lista de arquivos para copiar em um arquivo em outro lugar (mas as coisas ficam bem menos elegantes):

cd ..
find . -type f -print0 > /tmp/filelist
xargs -0 cp --parents -t folder/tmp < /tmp/filelist
rm /tmp/filelist

Você pode evitar o requisito sobre o% GNUcp usando cpio :

cd ..
find . -type f -print0 > /tmp/filelist
cpio -pmd0 folder/tmp < /tmp/filelist
rm /tmp/filelist

ou

cd ..
find . -type f -print0 | sponge | cpio -pmd0 folder/tmp

Se tmp estiver vazio, você também pode evitar o requisito em moreutils :

cd ..
find . -path ./folder/tmp -prune -o -type f -print0 | cpio -pmd0 folder/tmp
    
por 27.05.2015 / 22:04
0

Para uso interativo, eu tenho um hack para o caso análogo com mv:

cd ..
mv * tmp

mv: cannot move ‘tmp’ to a subdirectory of itself, ‘tmp/tmp’

Ignore o erro, todo o resto foi movido :-P. Não funciona da mesma maneira com o cp, ele cria um tmp / tmp vazio, que provavelmente não é o que você quer.

    
por 27.05.2015 / 22:15
0

Com pax , para copiar . para subdir/tmp , ignorando subdir/tmp :

mkdir -p subdir/tmp &&
  pax -rws'|^\./subdir/tmp/.*||' . subdir/tmp

Como alternativa, você pode fazer algo como:

mkdir -p subdir/tmp/subdir &&
  ln -s tmp subdir/tmp/subdir/tmp &&
  cp -a . subdir/tmp

subdir/tmp/subdir/tmp é, então, um link simbólico para si mesmo, e cp não poderá criar nada sob ele. Você pode substituí-lo com um diretório vazio depois, se quiser.

    
por 29.05.2015 / 17:10