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

Comment copier les liens symboliques ?

J'ai un répertoire qui contient quelques 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

Je dois les copier dans le répertoire actuel. Les liens résultants doivent être indépendants de leurs prototypes et mener directement à leurs 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 des liens relatifs vers des répertoires non fonctionnels

Que dois-je faire ?

Réponses (10)

212
212
212
2010-05-07 05:02:45 +0000
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 récursivement - et voir le résultat. Bien sûr, c'est juste une préférence personnelle.

Quant à savoir pourquoi vos autres options n'ont pas fait ce que vous attendiez, -s fait un lien au lieu de la copie et -L suit les liens dans la source pour trouver le fichier à copier au lieu de copier les liens eux-mêmes.

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

Comme le dit la page d'accueil, utilisez -P.

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

Si les liens contiennent des chemins relatifs, alors la copie du lien n'ajustera 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 souhaitez conserver les chemins relatifs, alors l'option -P de cp, comme l'a dit Ignacio Vazquez-Abrams, est ce qu'il vous faut.

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

Comme certains l'ont fait remarquer :

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

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é faite de manière récursive et j'ai pu avoir un retour visuel du processus :

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

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

C'est un peu exagéré pour copier juste quelques liens symboliques, mais si vous essayez en fait de copier une arborescence entière, 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, donc les liens symboliques dans la copie miroir pointeront vers les mêmes endroits que ceux de l'arborescence originale.

Cette astuce utilise des sous-coques pour mettre la commande tar en position à la racine du répertoire à mettre en miroir ; vous pouvez laisser l'une d'elles (avec la commande cd associée) si vous êtes 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 user@example.com '( cd /path/to/dest ; tar xf - )'

Encore une fois, cette astuce n'est pas appropriée pour chaque fois que vous voulez copier des liens symboliques, mais c'est un extrait très utile à connaître.

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

Essayez : 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

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

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

Utilisez l'option -P, comme Ignacio Vazquez-Abrams écrit ci-dessus . Ce qu'il n'a pas mentionné, c'est que -P n'a aucun effet sans -R. Il faut donc au moins cp -RP.

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

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

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

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/ copie avec déréférencement du lien, N/a, N/b (comme DIR/a)

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

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

se référer à man cp ou cp --help pour plus d'options.