Pour une utilisation dans un script Shell, je cherche un moyen de ligne de commande pour obtenir la destination d'un lien symbolique. Le plus proche que je suis venu jusqu'ici est stat -N src
, qui génère src -> dst
. Bien sûr, je pourrais analyser la sortie et obtenir dst
, mais je me demande s'il existe un moyen direct d'obtenir la destination.
Une autre option serait d'utiliser la commande spécialement conçue readlink
si elle est disponible.
Par exemple.
$ readlink -f `command -v php`
/usr/bin/php7.1
Sur Mac OS X et FreeBSD/NetBSD/etc. ses:
stat -f %Y <filename>
Plus généralement, je suppose que la solution est (stat --printf =% N utilise des guillemets étranges):
ls -l b | sed -e 's/.* -> //'
Exemple:
# ln -s a b
# stat -f %Y b
a
Une autre méthode consiste à:
# find b -maxdepth 0 -printf %l
a#
La dernière ligne est modifiée car elle n'a pas de nouvelle ligne, mais c'est bien si vous avez besoin du résultat dans une variable, comme ceci
# f=$(find b -maxdepth 0 -printf %l)
# echo $f
a
Le -maxdepth
est nécessaire pour empêcher find
de descendre dans les répertoires si b
se trouve être un répertoire.
Cela peut être fait en utilisant GNU find
: find src -Prune -printf "%l\n"
.
Realpath portable pur Bash
bash_realpath() {
# print the resolved path
# @params
# 1: the path to resolve
# @return
# &1: the resolved link path
local path="${1}"
while [[ -L ${path} && "$(ls -l "${path}")" =~ -\>\ (.*) ]]
do
path="${BASH_REMATCH[1]}"
done
echo "${path}"
}
Portablement: pas de chance, sauf en utilisant des heuristiques pour analyser la sortie ls -l, ou utiliser Perl -le 'print readlink("some-file")'
certains systèmes ont une commande readlink
, certains avec une -f
option pour obtenir le chemin absolu.
Il existe différentes implémentations d'une commande stat
comme wrapper pour les appels système stat
/lstat
. Le GNU celui n'est pas utile à cet égard, mais celui intégré à zsh l'est davantage:
zmodload zsh/stat
stat +link the-link
Toujours avec zsh, vous pouvez obtenir le chemin absolu d'un fichier (supprime chaque composant de lien symbolique) avec le :A
modificateur (s'applique à l'expansion des variables, à l'expansion de l'historique et à la globalisation:
~$ gstat -c %N b
`b' -> `a'
~$ var=b
~$ echo $var:A
/home/me/a
~$ echo b(:A)
/home/me/a
~$ echo ?(@:A)
/home/me/a
Sur un système où je n'ai pas de commandes readlink
ou stat
mais j'ai Python 2.x, j'utilise un petit script:
#!/usr/bin/env python
import os, sys
if __name__ == "__main__":
src = sys.argv[1]
target = os.readlink(src)
if not os.path.isabs(target):
target = os.path.abspath(os.path.join(os.path.dirname(src), target))
print target
Notez que contrairement à readlink -f
cela ne peut suivre qu'un seul niveau de lien symbolique.
realpath
commande du package coreutils
,
comme lié dans la page de manuel de la commande readlink
.
par exemple:
realpath /bin/python
les sorties
/usr/bin/python2.7
sur ma machine.