2010-05-07 04:36:38 +0000 2010-05-07 04:36:38 +0000
188
188

Como copiar links simbólicos?

Eu tenho um directó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

Preciso de os copiar para o directório actual. Os links resultantes devem ser independentes dos seus protótipos e levar directamente aos objectos alvo.

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

O que devo fazer?

Respostas (10)

212
212
212
2010-05-07 05:02:45 +0000
cp --preserve=links

A partir da página homem:

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

Pessoalmente, eu uso cp -av para a maior parte das minhas cópias pesadas. Desta forma, posso preservar tudo - mesmo de forma recorrente - e ver os resultados. Claro, isso é apenas uma preferência pessoal.

Quanto à razão pela qual as suas outras opções não fizeram o que esperava, -s faz um link em vez de copiar e -L segue os links na fonte para encontrar o ficheiro a copiar em vez de copiar os próprios links.

47
47
47
2010-05-07 04:39:24 +0000

Tal como diz a página de homem, use -P.

30
30
30
2010-05-07 05:09:01 +0000

Se as ligações contêm trajectórias relativas, então, a cópia da ligação não ajustará a trajectória relativa. Utilize o readlink, com o switch -f a seguir recursivamente, de modo a obter o caminho absoluto da ligação. Por exemplo:

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

Se preservar os caminhos relativos é o que pretende, então a opção -P do cp, como disse Ignacio Vazquez-Abrams, é o que precisa.

24
24
24
2015-01-27 14:51:13 +0000

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
11
11
11
2012-05-15 17:25:32 +0000

Usei o seguinte para duplicar um directório realmente grande. Todas as ligações simbólicas foram preservadas, a cópia foi feita de forma recorrente e pude ter algum feedback visual do processo:

cp -Prv /sourcer_dir/* /target_dir
11
11
11
2010-05-07 06:03:32 +0000

Na maioria das vezes, quando preciso de copiar muitos links simbólicos, estou na verdade a tentar espelhar uma árvore de directórios. Por isso quero os links simbólicos e tudo o resto.

Isto é um exagero para copiar apenas alguns links simbólicos, mas se estiver a tentar copiar uma árvore inteira, isto pode ser muito útil:

Use tar.

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

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

Este truque faz uso de subshells para colocar o comando tar na raiz do directório a ser espelhado; pode deixar um deles de fora (juntamente com o comando cd associado) se já estiver nos directó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 user@example.com '( cd /path/to/dest ; tar xf - )'

Mais uma vez, isto não é apropriado para cada vez que quiser copiar links simbólicos, mas é um snippet muito útil para saber.

4
4
4
2011-07-27 13:15:51 +0000

Experimente: cp -pr symlink destination

[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)

3
3
3
2015-12-01 12:51:43 +0000

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

cp --no-dereference --preserve=links
2
2
2
2019-01-12 17:55:13 +0000

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

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

1
1
1
2018-06-26 03:24:57 +0000

cp -s e cp -L são comandos especiais. Para o seu requisito, não use nenhum.

por exemplo, Copiar um directório DIR contendo a e uma ligação simbólica b apontando para a.

  • cp -s DIR/* N/ cria uma ligação simbólica em vez de copiar, N/a->…/DIR/a (ligação) e N/b->(. ./DIR/b) que é link para um link
  • cp -L DIR/* N/ copia com desreferenciação de link, N/a, N/b (igual a DIR/a)

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

  • - -P no-dereference, preserve links
  • -d combina a opção -P com -p para preservar=mode,ownership,timestamps
  • - -a combina a opção -d com -R para copiar recursivamente diretórios

referir man cp ou cp --help para mais opções.