web-dev-qa-db-fra.com

Bash: comment obtenir le vrai chemin d'un lien symbolique?

Est-il possible, en exécutant un fichier lié dans le dossier/usr/local/bin, d'obtenir le chemin absolu du script original? Eh bien, je sais où se trouve le fichier d'origine et je le sais parce que je le relie. Mais, ... je veux que ce script fonctionne, même si je déplace le code source d'origine (et le lien symbolique).

#!/bin/bash
echo "my path is ..."
14
sensorario

readlink n'est pas une commande standard, mais elle est courante sur Linux et BSD, y compris OS X, et c'est la réponse la plus simple à votre question. Les implémentations BSD et GNU readlink sont différentes, alors lisez la documentation de celle que vous avez.

Si readlink n'est pas disponible, ou si vous devez écrire un script multiplateforme qui n'est pas lié à une implémentation spécifique:

Si le lien symbolique est également un répertoire, alors

cd -P "$symlinkdir"

vous mettra dans le répertoire déréférencé, donc

echo "I am in $(cd -P "$symlinkdir" && pwd)"

fera écho au répertoire entièrement déréférencé. Cela dit, cd -P déréférence tout le chemin, donc si vous avez plus d'un lien symbolique dans le même chemin, vous pouvez avoir des résultats inattendus.

Si le lien symbolique est vers un fichier, pas un répertoire, vous n'aurez peut-être pas besoin de déréférencer le lien. La plupart des commandes suivent les liens symboliques sans danger. Si vous souhaitez simplement vérifier si un fichier est un lien, utilisez test -L.

21
kojiro

supposons que nous avons un vrai script ou fichier et un lien symbolique vers celui-ci:

$ ls -la
-rwxr-xr-x 1 root    root  0 Mar 20 07:05 realscript.sh
lrwxrwxrwx 1 root    root 10 Mar 20 07:05 symlink -> realscript.sh

Et la partie de GNU coreutils sont quelques commandes très utiles:

$ realpath symlink
/home/test/realscript.sh

voir aussi sur l'original:

realpath realscript.sh
/home/test/realscript.sh

Une très bonne combinaison de scripts consiste également à utiliser dirname sur les enregistrements enregistrés.

$ dirname /home/test/realscript.sh
/home/test

donc pour conclure, vous pouvez utiliser dans le script

echo  $( dirname $(realpath "symlink") )

ou pour obtenir et stocker dans le répertoire d'accueil du script réel variable:

script_home=$( dirname $(realpath "$0") )
echo Original script home: $script_home

Pour tout tester, nous mettons le lien symbolique dans/home/test2 /, modifions quelques éléments supplémentaires et l'exécutons/l'appelons depuis le répertoire racine:

/$ /home/test2/symlink
/home/test
Original script home: /home/test
Original script is: /home/test/realscript.sh
Called script is: /home/test2/symlink

Veuillez essayer d'écrire vous-même les sorties modifiées :)

7
Arunas Bartisius

si vous travaillez sur Linux readlink -f $LINK et sur mac, vous pouvez également utiliser ce greadlink -f $LINK