Scopri la destinazione simbolica del collegamento tramite riga di comando


130

Dì che ho impostato un collegamento simbolico:

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

c'è un modo per vedere qual è l'obiettivo della myothertextfile.txtlinea di comando?

Risposte:


171

Usa la -fbandiera per stampare la versione canonicalizzata. Per esempio:

readlink -f /root/Public/myothertextfile.txt

Da man readlink:

-f, --canonicalize
      canonicalize by following every symlink in every component of the given name recursively; all but the last component must exist

8
Come suggerito in un'altra domanda , potresti voler usare readlink -f.
Denilson Sá Maia,

5
Per ottenere questo lavoro su Mac OS X, brew install coreutils. In questo modo vengono installate le versioni gnu di base dei comandi precedute dalla lettera g, ovverogreadlink -f somefile
Mike D,

con l'opzione -f, il comando non restituisce nulla nel mio caso ..
Sotn

L'uso di -f mi ha dato le informazioni che desideravo, ovvero la risoluzione di più collegamenti simbolici e la visualizzazione dell'obiettivo finale.
Isapir,

nelle Ubuntu 18.04.1 LTS (Bionic Beaver)manpage di readlink hanno una nota che dice "Nota realpath (1) è il comando preferito da usare per la funzionalità di canonicalizzazione".
Sam Kamensky,

23

readlink è il comando che desideri. Dovresti guardare la pagina man per il comando. Perché se vuoi seguire una catena di collegamenti simbolici al file effettivo, allora hai bisogno dell'opzione -e o -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

Niente di sbagliato nella prima risposta, ma questa è più completa e utile.
Mike S,

6

Questo funzionerà anche:

ls -l /root/Public/myothertextfile.txt

ma readlinksarebbe preferito per l'uso in uno script piuttosto che per l'analisi ls.


4

Se vuoi mostrare la fonte e la destinazione del link, prova stat -c%N files*. Per esempio

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

Non è buono per l'analisi (utilizzare readlinkper quello), ma mostra il nome e la destinazione del collegamento, senza il disordine dils -l

-cpuò essere scritto --formate %Nsignifica "nome file citato con dereference se collegamento simbolico".


2

Il readlinkè una buona cosa, ma GNU-specifica e la piattaforma non croce. Scrivevo script multipiattaforma per /bin/sh, quindi userei qualcosa del tipo:

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

o:

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

ma questi devono essere testati su piattaforme diverse. Penso che funzioneranno, ma non sono sicuro al 100% per il lsformato di output.

Il risultato di lspuò anche essere analizzato all'interno bashsenza dipendere da un comando esterno come awk, sedo perl.

Questa bash_realpathfunzione risolve la destinazione finale di un collegamento (collegamento → collegamento → collegamento → finale):

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

Se non è possibile utilizzare readlink, l'analisi del risultato ls -lpotrebbe essere eseguita in questo modo.

Il risultato normale sarebbe:

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

Quindi vogliamo sostituire tutto prima di "->" e la freccia inclusa. Potremmo usare sedper questo:

ls -l /root/Public/myothertextfile.txt | sed 's/^.* -> //'
/root/Public/mytextfile.txt

1

La domanda non è abbastanza precisa per dare una risposta semplice come quella del Brasile-Brasile:

readlink -f some_path

dereferenzerà ogni collegamento simbolico coinvolto nel costrutto del percorso verso l' obiettivo finale dietro some_path.

Ma un livello di collegamenti simbolici a cascata è solo un caso particolare tra gli altri in un sistema, il caso generale è N livelli di collegamenti simbolici a cascata. Guarda quanto segue sul mio sistema:

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

rwhichè la mia implementazione ricorsiva whichche stampa tutti i collegamenti simbolici a cascata intermedi (a stderr) fino al bersaglio finale (a stdout).

Quindi se voglio sapere cos'è:

  • il target di symlink / usr / bin / emacs **, la risposta ovvia per me è /etc/alternatives/emacscome restituito da:

    readlink $(which emacs)
    readlink /usr/bin/emacs
    
  • l' obiettivo finale dietro i symlink / usr / bin / emacs a cascata , la risposta deve essere /usr/bin/emacs24-xcome restituita da:

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

0

llo ls -ldovrebbe elencare gli elementi della directory, incluso il tuo link simbolico e il suo target

cd -P /root/Public/myothertextfile.txt (nel tuo caso) dovrebbe puntare al percorso originale


0

Se trovi la destinazione di tutti i collegamenti all'interno di una cartella e la sua sottocartella usa il find . -type l -lscomando con il tipo di collegamento come segue:

me@local.localdomain:~/test$ find . -type l -ls
8601855888        0 lrwxr-xr-x    1 me           staff                   6 Jan 24 19:53 ./link -> target

Se vuoi il target di un singolo, allora ls -ldovrebbe funzionare:

me@local.localdomain:~/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
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.