216 votes

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

Je dois les copier dans le répertoire actuel. Les liens résultants doivent être indépendants de leurs prototypes et mener directement à leurs cibles.

  • cp -s crée des liens vers des liens, ce qui n'est pas un comportement 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?

244voto

jahid65 Points 1987
cp --preserve=liens

De la page de manuel :

   --preserve[=ATTR_LIST]
          préserver les attributs spécifiés (par défaut : mode,
          propriétaire, horodatages), si possible d'autres attributs : contexte,
          liens, xattr, all

Personnellement, j'utilise cp -av pour la plupart de mes copies importantes. De cette façon, je peux préserver tout - même de manière récursive - et voir la sortie. Bien sûr, c'est juste une préférence personnelle.

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

63voto

Tout comme le manuel l'indique, utilisez -P. Ce paramètre indique :

-P, --no-dereference
       ne jamais suivre les liens symboliques dans la SOURCE

33voto

mrucci Points 9408

Si les liens contiennent des chemins relatifs, alors, en copiant le lien, le chemin relatif ne sera pas ajusté. Utilisez readlink, avec l'option -f pour suivre de manière récursive, afin d'obtenir le chemin absolu du lien. Par exemple:

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

Si vous souhaitez préserver les chemins relatifs, alors l'option -P de cp, comme l'a dit Ignacio Vazquez-Abrams, est ce dont vous avez besoin.

32voto

Juh_ Points 421

Comme quelques-uns l'ont commenté :

cp -a 

fonctionne bien.

D'après le manuel :

-a    équivalent à -dR --preserve=all

-R    copie les répertoires de manière récursive
-d    équivalent à --no-dereference --preserve=links
--no-dereference   ne jamais suivre les liens symboliques dans la SOURCE

13voto

user12786 Points 454

La plupart du temps, quand j'ai besoin de copier de nombreux liens symboliques, c'est en fait pour recréer une arborescence de répertoires. Donc je veux les liens symboliques et tout le reste.

C'est exagéré pour copier juste quelques liens symboliques, mais si vous essayez en fait de copier un arbre entier, cela peut être très utile :

Utilisez tar.

user@host:/cwd$ ( cd /chemin/vers/src ; tar cf - . ) | ( cd /chemin/vers/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 emplacements que ceux de l'arborescence originale.

Cette astuce utilise des sous-shell pour positionner la commande tar à la racine du répertoire à copier en miroir ; vous pouvez en laisser un de côté (ainsi que la commande cd associée) si vous êtes déjà dans les répertoires src ou dest :

# déjà dans src ?
user@host:/src$ tar cf - . | ( cd /chemin/vers/dest ; tar xf - )

# déjà dans dest ?
user@host:/dest$ ( cd /chemin/vers/src ; tar cf - . ) | tar xf -

# juste besoin de src/foo ?
# ce résultat sera une copie miroir à dest/foo 
user@host:/src$ tar cf - foo | ( cd /chemin/vers/dest ; tar xf - )

# miroir vers un autre système ?
user@host:/src$ tar cf - . | ssh user@example.com '( cd /chemin/vers/dest ; tar xf - )'

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

SistemesEz.com

SystemesEZ est une communauté de sysadmins où vous pouvez résoudre vos problèmes et vos doutes. Vous pouvez consulter les questions des autres sysadmins, poser vos propres questions ou résoudre celles des autres.

Powered by:

X