Trova solo la destinazione del collegamento simbolico


50

Per l'uso in uno script di shell, sto cercando un modo da riga di comando per ottenere la destinazione di un collegamento simbolico. Il più vicino a cui sono arrivato finora è stat -N srcquale uscita src -> dst. Ovviamente potrei analizzare l'output e ottenere dst, ma mi chiedo se esiste un modo diretto per ottenere la destinazione.

Risposte:


61

Un'altra opzione sarebbe quella di utilizzare il comando appositamente progettato, readlinkse disponibile.

Per esempio

$ readlink -f `command -v php`
/usr/bin/php7.1

21
Utilizzare readlink -fse si desidera conoscere l' ultimo target del collegamento simbolico e non solo quello successivo .
scai,

Buon punto! Dimenticato quello.
nikitautiu,

11
Si noti che -fè un'estensione non portatile di GNU readlink.
bahamat,

2
Quando readlink non sarebbe disponibile? Grazie.
tommy.carstensen,

2
@ tommy.carstensen readlink (1) è stato aggiunto a GNU coreutils nel 2003, quindi in questi giorni puoi probabilmente dipenderlo praticamente da tutti i sistemi che usano coreutils. (Cfr. Git.savannah.gnu.org/cgit/coreutils.git/commit/src/… )
Josip Rodin,

16

Su Mac OS X e FreeBSD / NetBSD / ecc. suo:

stat -f %Y <filename>

Più in generale suppongo che la soluzione sia (stat --printf =% N usa virgolette strane):

ls -l b | sed -e 's/.* -> //'

Esempio:

# ln -s a b
# stat -f %Y b
a

Un altro metodo è:

# find b -maxdepth 0 -printf %l
a#

L'ultima riga è alterata perché non ha una nuova riga, ma va bene se hai bisogno del risultato in una variabile, in questo modo

# f=$(find b -maxdepth 0 -printf %l)
# echo $f
a

Il -maxdepthè necessaria per evitare finddi scendere in directory se bsembra essere una directory.


Ho completamente sfiorato, stat --printf='%N\n'è esattamente quello che voglio, strane citazioni non mi disturbano, sono le stesse citazioni rm e ln
interattivo

Questo apparentemente non è portatile perché su Linux, stat di GNU coreutils (1) ha diversi parametri e stampa link -> destnell'output. La soluzione find (1) deve essere verificata se è con GNU findutils o in altro modo ...
Josip Rodin,

Per favore, non dimenticare di citare le tue espansioni variabili, echo $fsicuramente non produce ciò che ti aspetti quando il link simbolico punta /*(sì, è possibile)
Camusensei

3

Questo può essere fatto utilizzando GNU find: find src -prune -printf "%l\n".


1

Portabilmente: nessuna fortuna se non l'uso dell'euristica per analizzare l'output di ls -l o usare perl -le 'print readlink("some-file")'

alcuni sistemi hanno un readlinkcomando, altri con -fun'opzione per ottenere il percorso assoluto.

Esistono varie implementazioni di un statcomando come wrapper per le chiamate stat/ lstatsystem. Quello GNU non è utile al riguardo, ma quello incorporato di zsh lo è di più:

zmodload zsh/stat
stat +link the-link

Sempre con zsh, puoi ottenere il percorso assoluto di un file (rimuove tutti i componenti del collegamento simbolico) con il :Amodificatore (si applica all'espansione variabile, all'espansione della cronologia e al globbing:

~$ 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

Su un sistema in cui non ho comandi readlinko statcomandi ma ho Python 2.x, sto usando uno script breve:

#!/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

Si noti che diversamente da readlink -fciò può seguire solo un livello di collegamento simbolico.


1

Realpath portatile puro di 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}"
}

0

realpathcomando del coreutilspacchetto,

come collegato nella readlinkpagina del manuale del comando.


per esempio:

realpath /bin/python

uscite

/usr/bin/python2.7

sulla mia macchina.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.