web-dev-qa-db-fra.com

Comment copier des liens symboliques?

J'ai un répertoire qui contient des liens symboliques:

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

J'ai besoin de les copier dans le répertoire actuel. Les liens résultants doivent être indépendants de leurs prototypes et mener directement aux objets cibles.

  • cp -s crée des liens vers des liens dont le comportement n'est pas approprié.
  • cp -s -L refuse de copier des liens vers des répertoires
  • cp -s -L -r refuse de copier les liens relatifs dans un répertoire qui ne fonctionne pas

Que devrais-je faire?

173
Basilevs
cp --preserve=links

De la page de manuel:

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

Personnellement, j'utilise cp -av pour la plupart de mes copies lourdes. De cette façon, je peux tout conserver - même de manière récursive - et voir la sortie. Bien sûr, ce ne sont que des préférences personnelles.

-s crée un lien à la place de la copie et -L suit les liens dans la source pour rechercher le fichier à copier au lieu de copier les liens eux-mêmes.

193
kainosnous

Comme indiqué dans la page de manuel, utilisez -P.

Si les liens contiennent des chemins relatifs, la copie du lien ne modifiera pas le chemin relatif. Utilisez readlink, avec le commutateur -f à suivre récursivement, afin d’obtenir le chemin absolu du lien. Par exemple:

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

Si vous voulez conserver les chemins relatifs, alors vous avez besoin de l'option -P de cp, comme l'a dit Ignacio Vazquez-Abrams.

28
mrucci

Comme quelques-uns l'ont commenté:

cp -a 

fonctionne bien.

De l'homme:

-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
23
Juh_

La plupart du temps, lorsque je dois copier de nombreux liens symboliques, j'essaie en fait de refléter une arborescence de répertoires. Donc, je veux les liens symboliques et tout le reste.

C'est excessif pour la copie de quelques liens symboliques, mais si vous essayez de copier un arbre entier, cela peut être très utile:

Utilisez tar .

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

tar ne résout pas le lien symbolique par défaut; les liens symboliques dans la copie miroir pointeront donc vers les mêmes emplacements que ceux de l'arborescence d'origine.

Cette astuce utilise des sous-shell pour mettre en miroir la commande tar à la racine du répertoire; vous pouvez en laisser un (ainsi que la commande cd associée) si vous vous trouvez déjà dans les répertoires 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 - )'

Encore une fois, cela ne convient pas à chaque fois que vous voulez copier des liens symboliques, mais c'est un extrait de code très utile à connaître.

10
quack quixote

J'ai utilisé ce qui suit pour dupliquer un très grand répertoire. Tous les liens symboliques ont été préservés, la copie a été réalisée de manière récursive et j'ai pu obtenir un retour visuel du processus:

cp -Prv /sourcer_dir/* /target_dir
10
oarevalo

Essayez: cp -pr destination du lien symbolique

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

4
ebe0

Sur Ubuntu lors de la copie de liens et de fichiers dans un répertoire:

cp --no-dereference --preserve=links
3
Amiramix

Utilisez l'option -P, comme l'a écrit Ignacio Vazquez-Abrams ci-dessus . Ce qu'il n'a pas mentionné, c'est que -P n'a pas d'effet sans -R. Donc, vous avez besoin d'au moins cp -RP.

(Le site ne me permet pas encore de commenter, alors j'ai posté une réponse séparée.)

1
1234ru

cp -s et cp -L sont des commandes spéciales. Pour votre besoin, n'utilisez aucun.

par exemple. Copier un répertoire DIR contenant a et un lien symbolique b pointant vers a.

  • cp -s DIR/* N/crée un lien symbolique au lieu de copier, N/a -> ../ DIR/a (lien) et N/b -> (../ DIR/b) qui est un lien vers un lien
  • cp -L DIR/* N/copies avec déréférencement de liens, N/a, N/b (identique à DIR/a)

Ce dont vous avez besoin, c'est N/a (= DIR/a) et N/b -> ../ N/a; il suffit donc de copier sans dereferencing, en utilisant l'option cp -P. Je crois que c’est aussi la valeur par défaut pour cp.

  • -P pas de déréférence, préserve les liens
  • -d combine l'option -P avec -p pour conserver le mode =, la propriété, l'horodatage
  • -a combine l'option -d avec -R pour copier récursivement les répertoires

reportez-vous à man cp ou cp --help pour plus d'options.

1
Atif Hussain