Un système d'exploitation fournit-il un mécanisme (appel système - pas un programme en ligne de commande) pour changer le chemin référencé par un lien symbolique (lien symbolique) - autrement qu'en dissociant l'ancien et en en créant un nouveau?
Le standard POSIX ne le fait pas. Solaris 10 ne le fait pas. MacOS X 10.5 (Leopard) ne le fait pas. (Je suis assez certain que ni AIX ni HP-UX ne le font non plus. À en juger par cette liste d' appels système Linux, Linux n'a pas non plus un tel appel système.)
Y a-t-il quelque chose qui fait?
(Je m'attends à ce que la réponse soit "Non".)
Puisque prouver un négatif est difficile, réorganisons la question.
Si vous savez que certains systèmes d'exploitation (de type Unix) qui ne sont pas déjà répertoriés n'ont pas d'appel système pour réécrire la valeur d'un lien symbolique (la chaîne renvoyée par readlink()
) sans supprimer l'ancien lien symbolique et en créer un nouveau, veuillez l'ajouter - ou les - dans une réponse.
ln
commande (ou l'équiavalent API) écrasant l'ancien lien? Quel problème rencontrez-vous?Réponses:
AFAIK, non, vous ne pouvez pas. Vous devez le supprimer et le recréer.En fait, vous pouvez écraser un lien symbolique et ainsi mettre à jour le chemin référencé par celui-ci:EDIT : Comme l'OP l'a souligné dans un commentaire, l'utilisation de l'
--force
option feraln
effectuer un appel système àunlink()
avantsymlink()
. Ci-dessous, la sortie destrace
sur ma boîte Linux le prouvant:Donc je suppose que la réponse finale est "non".EDIT : Ce qui suit est copié de la réponse d' Arto Bendiken sur unix.stackexchange.com, vers 2016.
Cela peut en effet être fait de manière atomique
rename(2)
, en créant d'abord le nouveau lien symbolique sous un nom temporaire, puis en écrasant proprement l'ancien lien symbolique en une seule fois. Comme l'indique la page de manuel :Dans le shell, vous feriez cela avec
mv -T
comme suit:Vous pouvez
strace
cette dernière commande pour vous assurer qu'elle utilise bienrename(2)
sous le capot:Notez que dans ce qui précède, les deux
mv -T
etstrace
sont spécifiques à Linux.Sur FreeBSD, utilisez
mv -h
alternativement.Note de l'éditeur: c'est ainsi que Capistrano le fait depuis des années maintenant, depuis ~ 2.15. Voir cette demande d'extraction .
la source
Oui, vous pouvez!
la source
-f
option signifie «supprimer la destination existante» avant de créer la nouvelle. Donc, cette commande atteint le résultat, mais en faisantunlink(2)
suivi desymlink(2)
. Ce n'est pas le sujet de la question initiale. Notez également que la réponse acceptée et la réponse suivante la plus votée sont toutes deux utiliséesln -sf
pour faire le travail, mais comme lestrace
montre la sortie, c'est le casunlink()
etsymlink()
parce qu'il n'y a pas d'appel système pour modifier un lien symbolique.Il n'est pas nécessaire de dissocier explicitement l'ancien lien symbolique. Tu peux le faire:
(ou utilisez le lien symbolique équivalent et renommez les appels). C'est mieux que de dissocier explicitement la liaison car le changement de nom est atomique, vous pouvez donc être assuré que le lien pointera toujours vers l'ancienne ou la nouvelle cible. Cependant, cela ne réutilisera pas l'inode d'origine.
Sur certains systèmes de fichiers, la cible du lien symbolique est stockée dans l'inode lui-même (à la place de la liste de blocage) si elle est suffisamment courte; ceci est déterminé au moment de sa création.
En ce qui concerne l'affirmation selon laquelle le propriétaire et le groupe réels sont immatériels, symlink (7) sous Linux dit qu'il y a un cas où il est significatif:
la source
set -x -e; mkdir junk; ( cd junk; mkdir olddir newdir; ln -s olddir mylink; ls -ilR; ln -s newdir temp; ls -ilR; mv temp mylink; ls -ilR; ); rm -fr junk
. Si vous créez des fichiers oldfile et newfile au lieu de répertoires et exécutez le script équivalent (principalement en changeant olddir en oldfile, newdir en newfile), alors vous obtenez l'effet que vous attendiez. Juste une complexité supplémentaire! Merci pour votre réponse.Juste un avertissement aux bonnes réponses ci-dessus:
L'utilisation de la méthode -f / --force présente un risque de perdre le fichier si vous mélangez la source et la cible:
Bien sûr, c'est intentionnel, mais des erreurs se produisent généralement. Ainsi, supprimer et reconstruire le lien symbolique est un peu plus de travail mais aussi un peu plus économique:
qui garde au moins mon dossier.
la source
-f
ou--force
est toujours un peu dangereux; cela suppose que l'utilisateur sait de quoi il s'agit. Il est doublement mortel si vous l'utilisez habituellement (rm -fr …
chaque fois est dangereux).La dissociation et la création du nouveau ne feraient-elles pas la même chose à la fin de toute façon?
la source
ln --force
commande écrasera absolument un lien existant.ln (1)
, tandis que matt b. discute du fait quesymlink (2)
ne prend pas en charge l'écrasement. Vous avez tous les deux raison, et je dirais qu'en regardant la mise en œuvre deln (1)
serait le moyen le plus idomatique d'accomplir la procédure de dissociation-reconnexion.Juste au cas où cela aiderait: il existe un moyen d'éditer un lien symbolique avec midnight commander (mc). La commande de menu est (en français sur mon interface mc):
qui peut être traduit par:
Le raccourci est Cx Cs
Peut-être qu'il utilise en interne le
ln --force
commande en , je ne sais pas.Maintenant, j'essaie de trouver un moyen d'éditer tout un tas de liens symboliques à la fois (c'est comme ça que je suis arrivé ici).
la source
unlink()
suivi d'unsymlink()
, simplement parce que c'est ce que fournissent les systèmes de type Unix.Techniquement, il n'y a pas de commande intégrée pour modifier un lien symbolique existant. Cela peut être facilement réalisé avec quelques commandes courtes.
Voici une petite fonction bash / zsh que j'ai écrite pour mettre à jour un lien symbolique existant:
la source
unlink()
etsymlink()
avec la nouvelle valeur, qui est ce qui se passe dans les coulisses avec votre code. Personnellement, j'aimerais que la fonction insiste sur exactement deux (ou peut-être un multiple de deux) arguments et caution si l'invocation n'est pas correcte. C'est une perspective particulière, cependant.