web-dev-qa-db-fra.com

Comment puis-je modifier les liens symboliques?

Ma compréhension de base d'un lien symbolique est comme un fichier spécial, un fichier qui contient un chemin de chaîne vers un autre fichier. Le VFS du noyau en résume beaucoup, mais y a-t-il une raison pour laquelle les liens symboliques semblent impossibles à modifier?

En d'autres termes: puis-je modifier un lien symbolique? Sinon, pourquoi pas?


Je comprends qu'il existe différentes façons de remplacer les liens symboliques (deux alternatives sont actuellement dans la section des réponses) mais il serait intéressant d'obtenir une explication sur la raison pour laquelle le remplacement semble être le seul moyen de traiter les liens symboliques . Pourquoi ne pouvez-vous pas simplement changer de point

66
Oli

Étant donné que -f fait juste un remplacement silencieux, vous pouvez faire un remplacement atomique avec mv -T (-T le fait fonctionner même si /loc.../link est un répertoire) :

ln -s /location/to/link linkname
# ... 
ln -s /location/to/link2 newlink
mv -T newlink linkname

linkname est accessible tout au long du processus.

37
Oli

Si par modification, vous voulez changer le fichier vers lequel il pointe, alors oui vous pouvez:

$ ln -s .bashrc test
$ ls -al test
lrwxrwxrwx 1 Pascal pascal 7 2009-09-23 17:12 test -> .bashrc
$ ln -s .profile test
ln: creating symbolic link `test': File exists
$ ln -s -f .profile test
$ ls -al test
lrwxrwxrwx 1 Pascal pascal 8 2009-09-23 17:12 test -> .profile

Le paramètre -f (--force) Lorsqu'il est passé à ln, il appelle l'appel système unlink() juste avant symlink()

Tiré de ce qui suit réponse de débordement de pile .

23
NlightNFotis

Les liens symboliques doivent être modifiés atomiquement. Si vous êtes à mi-chemin de les écrire, ils ne fonctionneront pas. Le contenu d'un lien symbolique est assez petit (au maximum 4095 caractères sous Linux: la longueur maximale d'un chemin d'accès à un fichier), il serait donc inutile de modifier une partie d'un lien symbolique au niveau du noyau. Par conséquent, le noyau n'offre aucune interface pour éditer un lien symbolique, seulement une interface pour en créer un nouveau, l'appel système symlink (plus l'interface générique unlink pour supprimer n'importe quel fichier).

L'appel système symlink crée uniquement un nouveau lien symbolique, il ne supprime aucun fichier existant. C'est ennuyeux, mais cohérent avec d'autres appels système pour créer des fichiers tels que open (qui peut créer un nouveau fichier ou tronquer un fichier existant, mais pas remplacer un fichier existant par un fichier nouvellement créé) et mkdir.

Dans le Shell, comme vous avez découvert , alors que vous ne pouvez pas remplacer un lien symbolique de manière atomique par la commande ln (ln -sf dissocie le fichier précédent puis crée le lien symbolique), vous pouvez le faire en créant d'abord un lien symbolique sous un nom temporaire puis en le déplaçant en place.

tmp=$(TMPDIR=$(dirname -- "$link") mktemp)
ln -sf -- "$target" "$tmp"
mv -f "$tmp" "$link"

Techniquement, il n'y a pas de commande intégrée pour modifier un lien symbolique existant. Il peut être facilement réalisé avec quelques commandes courtes.

Voici un peu fonction bash/zsh J'ai écrit pour mettre à jour un lien symbolique existant:

# -----------------------------------------
# Edit an existing symbolic link
#
# @1 = Name of symbolic link to edit
# @2 = Full destination path to update existing symlink with 
# -----------------------------------------
function edit-symlink () {
    if [ -z "$1" ]; then
        echo "Name of symbolic link you would like to edit:"
        read LINK
    else
        LINK="$1"
    fi
    LINKTMP="$LINK-tmp"
    if [ -z "$2" ]; then
        echo "Full destination path to update existing symlink with:"
        read DEST
    else
        DEST="$2"
    fi
    ln -s $DEST $LINKTMP
    rm $LINK
    mv $LINKTMP $LINK
    printf "Updated $LINK to point to new destination -> $DEST"
}
0
blizzrdof77

Supposons que le nom du lien existe à la suite d'avoir fait (dans le passé):

 ln -s   /the/path/to/a/file   linkname

Ensuite, il existe trois façons de modifier le lien symbolique:

  • Utilisez ln avec -f forcer et même pour les répertoires -n (l'inode pourrait être réutilisé):

    ln -sfn /some/new/path linkname
    
  • Supprimez le lien symbolique et créez-en un nouveau (même pour les répertoires):

    rm linkname; ln -s /some/new/path linkname
    
  • créer un nouveau lien symbolique, puis mv it (changement atomique même pour les répertoires):

    ln -s  /some/new/path newlinkname
    mv -fT newlinkname linkname             # linkname remains after the command
    
0
Isaac