web-dev-qa-db-fra.com

Existe-t-il un moyen de modifier un lien symbolique sans le supprimer au préalable?

J'ai donc créé un lien symbolique:

ln -s /location/to/link linkname

Maintenant, je veux changer l'emplacement vers lequel le lien symbolique renvoie. Comment je fais ça? existe-t-il un moyen de le faire sans le supprimer au préalable?

60
Andrew

Vous pouvez créer le nouveau lien avec un nom différent, puis le déplacer pour remplacer l'ancien lien.

ln -s /location/to/link linkname

Plus tard

ln -s /location/to/link2 newlink
mv newlink linkname

Si newlink et linkname sont sur le même périphérique physique, le mv doit être atomique.

39
martin clayton

Essayez ln -sf new_destination linkname.

24
Phil

Si les cibles des liens symboliques sont des répertoires, vous devez ajouter le -T flag à la commande mv, sinon il déplace le nouveau lien symbolique vers le répertoire cible de l'ancien lien symbolique.

Exemple de passage atomique d'un site Web à une nouvelle version:

Configuration d'origine - le site Web est stocké dans www1 répertoire, vhost pointant sur www lien symbolique:

ln -s www1 www

Accédez au site Web, voir l'ancienne version.

Mettez de nouveaux fichiers de site Web dans de nouveaux www2 répertoire.

Configurer un nouveau lien symbolique vers un nouveau site Web:

ln -s www_new www2

Déplacer www lien symbolique vers le répertoire du nouveau site Web:

mv -T www_new www

Accédez au site Web, consultez immédiatement la nouvelle version.

17
ben_nuttall

Modifiez simplement la cible du lien symbolique:

# ln -sfT /path/to/new/target linkname

Il s'agit d'un changement atomique instantané.

14
Jake Wilson

Pour les répertoires, vous voulez faire: ln -sfT/location/to/new/target old_linkname

7
raa

Sous OSX, la page de manuel de ln indique que vous pouvez le faire comme ceci

ln -shf /location/to/link link name

Depuis la page de manuel:

The options are as follows:
 -F    If the target file already exists and is a directory, then remove it so that the link may occur.  The -F
       option should be used with either -f or -i options.  If none is specified, -f is implied.  The -F option is
       a no-op unless -s option is specified.

 -h    If the target_file or target_dir is a symbolic link, do not follow it.  This is most useful with the -f
       option, to replace a symlink which may point to a directory.

 -f    If the target file already exists, then unlink it so that the link may occur.  (The -f option overrides any
       previous -i options.)

 -i    Cause ln to write a Prompt to standard error if the target file exists.  If the response from the standard
       input begins with the character `y' or `Y', then unlink the target file so that the link may occur.  Other-
       wise, do not attempt the link.  (The -i option overrides any previous -f options.)

 -n    Same as -h, for compatibility with other ln implementations.

 -s    Create a symbolic link.

 -v    Cause ln to be verbose, showing files as they are processed.
6
jschank

Non. L'appel système symlink renverra EEXIST si newpath existe déjà. Vous pouvez uniquement créer un lien à partir d'un nouveau nœud dans le système de fichiers. Quelle est l'exigence ici? Si vous vous inquiétez d'une course en raison de la non-atomicité des appels de dissociation/lien symbolique, vous voudrez peut-être repenser un peu l'architecture pour assurer la synchronisation ailleurs. Il y a eu quelques bugs de sécurité effrayants introduits par ce genre de chose.

5
Andy Ross

Enchaînez les commandes comme ceci:

rm currentlink && ln -s /path/to/link currentlink

La première commande supprime celle existante et la seconde la crée immédiatement à nouveau.

4
Pete

Comme d'autres l'ont mentionné, vous devez d'abord supprimer le lien symbolique, manuellement ou en passant le -f flag à l'utilitaire ln.

Il y a des années, j'ai dû faire de petites modifications aux liens symboliques assez fréquemment, j'ai donc écrit un simple utilitaire basé sur readline (edln) pour rendre cela moins ennuyeux. Au cas où quelqu'un d'autre le trouverait utile, je l'ai mis en ligne sur https://github.com/jjlin/edln/ .

edln affichera la cible du lien symbolique d'origine; vous pouvez ensuite utiliser les touches fléchées ou les touches de lecture standard (M-b, M-f, C-d, etc.) pour vous déplacer et modifier la cible.

3
jjlin

Je viens de googler, je n'ai trouvé aucune bonne réponse et j'ai dû me résoudre:

ln -f -s -T `readlink SomeLibrary | sed 's/version.old/version.new/'` SomeLibrary

Modifier par définition signifie ne pas recréer à partir de zéro mais changer en partie. Toute réponse nécessitant de mémoriser un chemin, peut-être long ou avec des symboles étranges, est définitivement mauvaise.

0
user1046885