Como copiar links simbólicos?

180

Eu tenho um diretório que contém alguns links simbólicos:

user@host:include$ find .. -type l -ls
4737414    0 lrwxrwxrwx   1 user group       13 Dec  9 13:47 ../k0607-lsi6/camac -> ../../include
4737415    0 lrwxrwxrwx   1 user group       14 Dec  9 13:49 ../k0607-lsi6/linux -> ../../../linux
4737417    0 lrwxrwxrwx   1 user group       12 Dec  9 13:57 ../k0607-lsi6/dfc -> ../../../dfc
4737419    0 lrwxrwxrwx   1 user group       17 Dec  9 13:57 ../k0607-lsi6/dfcommon -> ../../../dfcommon
4737420    0 lrwxrwxrwx   1 user group       19 Dec  9 13:57 ../k0607-lsi6/dfcommonxx -> ../../../dfcommonxx
4737421    0 lrwxrwxrwx   1 user group       17 Dec  9 13:57 ../k0607-lsi6/dfcompat -> ../../../dfcompat

Eu preciso copiá-los para o diretório atual. Os links resultantes devem ser independentes de seus protótipos e levar diretamente aos objetos de destino.

  • cp -s cria links para links que não são um comportamento apropriado.
  • cp -s -L se recusa a copiar links para diretórios
  • cp -s -L -r se recusa a copiar links relativos para o diretório não ativo

O que devo fazer?

Basilevs
fonte
10
cp -dfez o trabalho do meu lado.
M-ric
2
cp -Rem um mac
Mirko

Respostas:

201
cp --preserve=links

Na página do manual:

   --preserve[=ATTR_LIST]
          preserve  the   specified   attributes   (default:   mode,owner-
          ship,timestamps),  if  possible  additional attributes: context,
          links, xattr, all

Pessoalmente, uso cp -av na maioria das minhas cópias pesadas. Dessa forma, posso preservar tudo - mesmo recursivamente - e ver a saída. Claro, isso é apenas preferência pessoal.

Por que suas outras opções não fizeram o que você esperava, -scria um link em vez de copiar e -Lsegue os links na fonte para encontrar o arquivo a ser copiado em vez de copiar os links em si.

kainosnous
fonte
3
Pode ser necessário adicionar -R, pois, caso contrário, o cp ignorará diretórios e links simbólicos para diretórios.
Olivier 'Ölbaum' Scherler
8
Tentei fazer isso no RedHat e ele não funciona
Mansuro
41
em um Mac? usecp -a
Steve Tauber
11
+1 para a -aopção. Heh, procurei as opções na página cpde manual inúmeras vezes, mas devo sempre ter passado por aqui. Até agora, estou usando -dpr, mas -aabrange todos eles, além da preservação de alguns outros atributos. Se eu precisasse desses outros atributos, provavelmente teria procurado a --preserveopção novamente e usado -dr --preserve=all, que é exatamente o que -aé! Bem, pelo menos eu sei agora - -aé perfeito e é isso que vou usar a partir de agora.
James Haigh
3
Isso não funcionou no Cygwin. --preserve=linksnão foi suficiente. Ainda dizia cp: omitting directory. Mas -avfuncionou.
21415 Chloe
44

Assim como a página de manual diz, use -P.

Ignacio Vazquez-Abrams
fonte
8
no Mac -Pnão funciona em diretórios então eu useicp -a
Steve Tauber
4
Obrigado, já vi e me beneficiei da sua resposta três vezes, agora diferentes, ao longo de um ano. Não consigo lembrar!
Siddhartha
Isso funciona, mas minha página de manual diz "-P nunca segue links simbólicos em SOURCE", que não é intuitivamente o mesmo que "copiar links simbólicos como links simbólicos para o destino". ( "nunca seguem" faz soar como ele funciona em combinação com -R)
RM
Isto cp -Pao contrário do top votado resposta por obras @kainosnous para mim. Obrigado!
tommy.carstensen
Trabalhos em Redhat. A resposta aceita não funciona!
Phiber
29

Se os links contiverem caminhos relativos, copiar o link não ajustará o caminho relativo. Use readlink, com a opção -fpara seguir recursivamente, para obter o caminho absoluto do link. Por exemplo:

ln -s $(readlink -f old/dir/oldlink) new/dir/newlink

Se você deseja preservar os caminhos relativos, a opção -Pde cp, como disse Ignacio Vazquez-Abrams, é o que você precisa.

mrucci
fonte
1
Pode ser uma má idéia desreferenciar recursivamente se tudo o que você está tentando fazer é converter os links simbólicos de relativos ao absoluto. A recursão não é necessária aqui e, às vezes, links simbólicos encadeados existem por um motivo. Os links simbólicos costumam ser usados ​​para especificar opções ou opções de configuração. Por exemplo, no meu sistema, há uma cadeia de links simbólicos /usr/share/dict/words -> /etc/dictionaries-common/words -> /usr/share/dict/british-englishque especifica o dicionário preferido. Se você desresferisse recursivamente essa cadeia, o link simbólico resultante ignoraria quaisquer alterações futuras nessa preferência.
James Haigh
24

Como alguns comentaram:

cp -a 

funciona bem.

Do homem:

-a    same as -dR --preserve=all

-R    copy directories recursively
-d    same as --no-dereference --preserve=links
--no-dereference   never follow symbolic links in SOURCE
Juh_
fonte
3
... mas apenas se nenhum dos links simbólicos for para caminhos relativos.
Michael Scheper
11

Eu usei o seguinte para duplicar um diretório muito grande. Todos os links simbólicos foram preservados, a cópia foi feita de forma recursiva e pude ter algum feedback visual do processo:

cp -Prv /sourcer_dir/* /target_dir
oarevalo
fonte
10

Na maioria das vezes, quando preciso copiar muitos links simbólicos, na verdade estou tentando espelhar uma árvore de diretórios. Então, eu quero os links simbólicos e tudo mais.

Isso é um exagero para copiar apenas alguns links simbólicos, mas se você estiver realmente tentando copiar uma árvore inteira, isso pode ser muito útil:

Use alcatrão .

user@host:/cwd$ ( cd /path/to/src ; tar cf - . ) | ( cd /path/to/dest ; tar xf - )

O tar não resolve o link simbólico por padrão; portanto, os links simbólicos na cópia espelhada apontam para os mesmos locais que os da árvore original.

Esse truque faz uso de subshells para colocar o comando tar na posição na raiz do diretório a ser espelhado; você pode deixar um deles de fora (junto com o comando cd associado ) se você já estiver nos diretórios src ou dest :

# already in src?
user@host:/src$ tar cf - . | ( cd /path/to/dest ; tar xf - )

# already in dest?
user@host:/dest$ ( cd /path/to/src ; tar cf - . ) | tar xf - 

# just need src/foo?
# this result will be a mirror copy at dest/foo 
user@host:/src$ tar cf - foo | ( cd /path/to/dest ; tar xf - )

# mirror to another system?
user@host:/src$ tar cf - . | ssh [email protected] '( cd /path/to/dest ; tar xf - )'

Novamente, isso não é apropriado para toda vez que você deseja copiar links simbólicos, mas é um trecho muito útil para saber.

charlatão quixote
fonte
1
tar é definitivamente mais portátil do que cp na minha experiência
don brilhante
4

Tente: destino de link simbólico cp -pr

[root@station1 temp]# ls -l
total 8
-rw-r--r-- 1 root root  0 Jul 27 18:40 abc
lrwxrwxrwx 1 root root 13 Jul 27 18:41 abc.link1 -> /tmp/temp/abc
[root@station1 temp]# cp -rp /tmp/temp/abc.link1 /tmp/temp/abc.link2
[root@station1 temp]# ls -l
total 12
-rw-r--r-- 1 root root  0 Jul 27 18:40 abc
lrwxrwxrwx 1 root root 13 Jul 27 18:41 abc.link1 -> /tmp/temp/abc
lrwxrwxrwx 1 root root 13 Jul 27 18:42 abc.link2 -> /tmp/temp/abc
[root@station1 temp]# 

OS - Centos 5 (Linux)

ebe0
fonte
3

No Ubuntu, ao copiar links e arquivos em um diretório:

cp --no-dereference --preserve=links
Greg
fonte
5
cp -dé o atalho para isso
hunse 30/05
1
Penso em ambos cp -ae cp --preserve=linksfaço mais do que a pergunta está perguntando. Pelo que entendi, esta é a resposta correta para quem usa cp, embora apenas com arquivos (sem diretórios) como na pergunta, --no-dereferencenão surtisse efeito.
palswim
2

Use a -Popção, como Ignacio Vazquez-Abrams escreveu acima . O que ele não mencionou é -Pque não tem efeito sem -R. Então você precisa pelo menos cp -RP.

(O site não me permite comentar ainda, por isso postei uma resposta separada.)

1234ru
fonte
Em uma caixa solaris antiga, meu cp não suporta -d. cp -rP funcionou para mim; (idk a diferença entre -R e -r, -r funciona para mim).
spioter 18/09
1

cp -s e cp -L são comandos especiais. Para sua exigência, não use nenhum.

por exemplo, copiar um diretório DIR contendo a e um link simbólico b apontando para a.

  • cp -s DIR / * N / cria um link simbólico em vez de copiar, N / a -> ../ DIR / a (link) e N / b -> (../ DIR / b), que é o link para um link
  • cp -L DIR / * N / cópias com desreferenciamento de link, N / a, N / b (o mesmo que DIR / a)

O que você precisa é N / a (= DIR / a) e N / b -> ../ N / a; então, basta copiar sem desreferenciar, usando a opção cp -P. Eu acredito que este também é o padrão para cp.

  • -P sem desreferência, preservar links
  • -d combina a opção -P com -p para preservar = modo, propriedade, registros de data e hora
  • -a combina a opção -d com -R para copiar recursivamente diretórios

consulte man cpou cp --helppara mais opções.

Atif Hussain
fonte