web-dev-qa-db-fra.com

Rechercher uniquement la destination du lien symbolique

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.

51
gerrit

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
63
nikitautiu

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.

18
Coroos

Cela peut être fait en utilisant GNU find: find src -Prune -printf "%l\n".

3
gerrit

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}"
}
1
Léa Gris

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
1
Stéphane Chazelas

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.

1
rakslice

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.

0
user86041