Existe uma maneira simples de recursivamente copiar todos os links simbólicos sob um diretório para outro diretório, preservando a estrutura?

2

Eu tenho um diretório ~/tmp/foo/ que é preenchido com subdiretórios, arquivos e links simbólicos.

$ tree ~/tmp/foo/
tmp/foo/
├── eggs
│   ├── baz
│   │   └── link3.txt -> /home/me/file3.txt
│   └── link2.txt -> /home/me/file2.txt
├── hello.txt
├── link1.txt -> /home/me/file1.txt
└── spam
    ├── link4.txt -> /home/me/file4.txt
    └── link5.txt -> /home/me/file5.txt

3 directories, 6 files

Eu quero recursivamente copiar todos os links simbólicos em ~/tmp/foo/ como arquivos (como se eu tivesse usado cp -rH ) para outro diretório (não vazio) ~/bar/ . Existe uma maneira simples de fazer isso?

Eu tentei o seguinte:

find ~/tmp/foo/ -type l -print | rsync -avzL --files-from=- ~/tmp/foo/ ~/tmp/bar/

Mas isso falha.

    
por Brian Fitzpatrick 11.01.2018 / 23:48

2 respostas

0

Verifique se o seu caminho de localização é "." e em relação ao seu caminho rsync porque o find inclui o prefixo do caminho nos resultados. Leia também as mensagens de erro do rsync que irá avisá-lo se você errar com algo parecido;

rsync: link_stat "/test/a/a/1/3.txt" failed: No such file or directory (2)

Aqui está um exemplo que funcionou para mim:

mkdir test
cd test
mkdir a b 
cd a
mkdir 1
echo 1 > 1/2.txt
ln -s 1/2.txt 1/3.txt
tree ../
../
├── a
│   └── 1
│       ├── 2.txt
│       └── 3.txt -> a/1/2.txt
└── b

então

find . -type l | rsync -av --files-from=- ./ ../b/
building file list ... done
./
1/
1/3.txt -> a/1/2.txt

sent 99 bytes  received 25 bytes  248.00 bytes/sec
total size is 9  speedup is 0.07
tree ../
../
├── a
│   └── 1
│       ├── 2.txt
│       └── 3.txt -> a/1/2.txt
└── b
    └── 1
        └── 3.txt -> a/1/2.txt

4 directories, 3 files

Se por fracassado você quer dizer que o comando -L (mudando um / 1 / 2.txt para b / 1 / 2.txt) faz com que não funcione, então ... Eu não sei por que isso acontece, mas eu gostaria contornar com mount --bind --make-slave .

    
por 12.01.2018 / 00:15
0

Se você não se importar em copiar o arquivo regular foo / hello.txt, você pode usar:

$ cp -RLv ~/foo/ ~/bar/

A opção -L instrui cp a cancelar a referência a todos os links simbólicos encontrados na árvore. Ele difere da opção -H , que instrui a desreferenciação de links simbólicos apenas dos argumentos da linha de comando.

No entanto, se você pretende copiar os links e os links simbólicos exclusivamente, a única idéia que tenho é tornar a sua sugestão de linha de comando um pouco mais complicada:

$ ( cd ~/tmp/foo/ ; find -mindepth 1 '(' -type l -o -type d ')' -print | cut -b 3- ) | rsync -avzL --files-from=- ~/tmp/foo/ ~/tmp/bar/

A ideia é:

  • Os parâmetros find são modificados para retornar links simbólicos e diretórios e para retornar caminhos um nível abaixo (para que não retorne a entrada '.')

  • O parâmetro --files-from= rsync requer caminhos relativos. Então, tive que forçar o comando find a ser executado no diretório de origem, usando ( cd ~/tmp/foo ; find )

  • O cut -b 3- corta o prefixo ./ da find de saída.

por 12.01.2018 / 03:45

Tags