Connaître la cible du lien symbolique via la ligne de commande

130

Dites que je crée un lien symbolique:

ln -s /root/Public/mytextfile.txt /root/Public/myothertextfile.txt

Y at-il un moyen de voir ce que la cible de myothertextfile.txtutilise la ligne de commande?

Jared
la source

Réponses:

171

Utilisez le -fdrapeau pour imprimer la version canonisée. Par exemple:

readlink -f /root/Public/myothertextfile.txt

De man readlink:

-f, --canonicalize
      canonicalize by following every symlink in every component of the given name recursively; all but the last component must exist
brian-brésil
la source
8
Comme suggéré dans une autre question , vous voudrez peut-être utiliser readlink -f.
Denilson Sá Maia
5
Pour obtenir ce travail sous Mac OS X, brew install coreutils. Cela installe les versions de base des commandes gnu avec le préfixe g, c'estgreadlink -f somefile
Mike D
avec l'option -f, la commande ne retourne rien dans mon cas ..
dimanche
L'utilisation de -f m'a fourni les informations souhaitées, à savoir la résolution de plusieurs liens symboliques et l'affichage de la cible finale.
Isapir
sur Ubuntu 18.04.1 LTS (Bionic Beaver)les pages de manuel de readlink, une note indiquant "Remarque: realpath (1) est la commande à utiliser de préférence pour la fonctionnalité de canonisation".
Sam Kamensky
23

readlink est la commande que vous voulez. Vous devriez regarder la page de manuel pour la commande. Parce que si vous voulez suivre une chaîne de liens symboliques vers le fichier réel, vous avez besoin du commutateur -e ou -f:

$ ln -s foooooo zipzip   # fooooo doesn't actually exist
$ ln -s zipzip zapzap

$ # Follows it, but doesn't let you know the file doesn't actually exist
$ readlink -f zapzap
/home/kbrandt/scrap/foooooo

$ # Follows it, but file not there
$ readlink -e zapzap

$ # Follows it, but just to the next symlink
$ readlink zapzap
zipzip
Kyle Brandt
la source
Rien de mal avec la première réponse, mais celle-ci est plus complète et utile.
Mike S
6

Cela fonctionnera également:

ls -l /root/Public/myothertextfile.txt

mais readlinkserait préférable pour une utilisation dans un script plutôt que l'analyse ls.

Dennis Williamson
la source
4

Si vous souhaitez afficher la source et la destination du lien, essayez stat -c%N files*. Par exemple

$ stat -c%N /dev/fd/*
‘/dev/fd/0’ -> ‘/dev/pts/4’
‘/dev/fd/1’ -> ‘/dev/pts/4’

Ce n’est pas bon pour l’analyse (à utiliser readlinkpour ça), mais il montre le nom du lien et la destination, sans le fouillis dels -l

-cpeut être écrit --formatet %Nsignifie “nom de fichier cité avec déréférence si lien symbolique”.

Robert Siemer
la source
2

C'est readlinkune bonne chose, mais spécifique à GNU et non multi-plateforme. J'avais l'habitude d'écrire des scripts inter-plateformes pour /bin/sh, donc j'utiliserais quelque chose comme:

 ls -l /root/Public/myothertextfile.txt | awk '{print $NF}'

ou:

 ls -l /root/Public/myothertextfile.txt | awk -F"-> " '{print $2}'

mais ceux-ci doivent être testés sur différentes plates-formes. Je pense qu'ils fonctionneront, mais ne sont pas sûrs à 100% du lsformat de sortie.

Le résultat de lspeut également être analysé à l'intérieur bashsans dépendre d'une commande externe telle que awk, sedou perl.

Cette bash_realpathfonction résout la destination finale d'un lien (lien → lien → lien → final):

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}"
}
Роман Коптев
la source
1

Si vous ne pouvez pas utiliser readlink, alors l'analyse du résultat de ls -lpourrait être faite comme ceci.

Le résultat normal serait:

ls -l /root/Public/myothertextfile.txt
lrwxrwxrwx 1 root root 30 Jan  1 12:00 /root/Public/myothertextfile.txt -> /root/Public/mytextfile.txt

Nous voulons donc tout remplacer avant "->" et la flèche incluse. Nous pourrions utiliser sedpour cela:

ls -l /root/Public/myothertextfile.txt | sed 's/^.* -> //'
/root/Public/mytextfile.txt
7ochem
la source
1

La question n'est pas assez précise pour donner une réponse simple comme celle de brian-brazil:

readlink -f some_path

déréférencera chaque lien symbolique impliqué dans la construction de chemin vers la cible finale située derrière some_path.

Mais un niveau de liens symboliques en cascade n'est qu'un cas particulier parmi d'autres dans un système, le cas général étant N niveaux de liens symboliques en cascade. Regardez ce qui suit sur mon système:

$ rwhich emacs
/usr/bin/emacs
 /etc/alternatives/emacs
  /usr/bin/emacs24-x

rwhichest ma propre implémentation récursive whichqui affiche tous les liens symboliques en cascade intermédiaires (to stderr) vers la cible finale (to stdout).

Alors si je veux savoir ce qui est:

  • la cible de symlink / usr / bin / emacs **, la réponse évidente est la réponse /etc/alternatives/emacsrenvoyée par:

    readlink $(which emacs)
    readlink /usr/bin/emacs
    
  • la cible finale derrière les liens symboliques en cascade / usr / bin / emacs, la réponse doit être /usr/bin/emacs24-xrenvoyée par:

    readlink -f $(which emacs)
    readlink -f /usr/bin/emacs
    rwhich emacs 2>/dev/null
    
Nico
la source
0

llou ls -ldevrait lister les éléments du répertoire, y compris votre lien symbolique et sa cible

cd -P /root/Public/myothertextfile.txt (dans votre cas) devrait indiquer le chemin d'origine

Mantz
la source
0

Si vous trouvez la cible de tous les liens dans un dossier et son sous-dossier, utilisez la find . -type l -lscommande avec le type de lien comme suit:

[email protected]:~/test$ find . -type l -ls
8601855888        0 lrwxr-xr-x    1 me           staff                   6 Jan 24 19:53 ./link -> target

Si vous voulez la cible d'un seul, alors ls -ldevrait fonctionner:

[email protected]:~/test$ ls -l 
total 0
lrwxr-xr-x  1 me  staff  6 Jan 24 19:53 link -> target
-rw-r--r--  1 me  staff  0 Jan 24 19:53 target
Memin
la source