Come ottenere il percorso completo del file originale di un collegamento simbolico soft?


99

Voglio scpun file su un server. Il file è un collegamento simbolico, e in realtà quello che voglio fare è copiare il file sorgente. Comunque non voglio tracciare manualmente il percorso del file sorgente, perché può essere sostituito. Se riesco a ottenere il percorso assoluto del file sorgente, posso sepfarlo. Come posso ottenere il percorso?


2
La maggior parte delle scpversioni segue i collegamenti simbolici per impostazione predefinita, vero? Dovresti controllare il tuo e magari risparmiarti un po 'di lavoro.
jw013,

@ jw103 Grazie per avermelo fatto notare. Non lo sapevo. :)
Eonil,

2
Nota: scp -rforza i seguenti collegamenti simbolici.
Eonil,

Risposte:


129

Prova questa linea:

readlink -f `which command`

Se commandè nella tua $PATHvariabile, altrimenti devi specificare il percorso che conosci.


12
-frestituirà un percorso a un target finale inesistente, purché esistano target di link intermedi ... Utilizzare -eper evitarlo, ad es. -erestituirà null se il target finale non esiste.
Peter.O

10
-ferrato con readlink: illegal option -- fin OSX. Rimuovendolo ha funzionato bene.
Heath Borders,

2
@HeathBorders Per OSX se hai installato coreutils homebrew puoi anche usare greadlink.
Adam Gent,

23

Sotto Linux, readlinklegge il contenuto di un collegamento simbolico e readlink -fsegue collegamenti simbolici a collegamenti simbolici a collegamenti simbolici, ecc., Fino a quando non trova qualcosa che non è un collegamento simbolico.

Questo non è necessario per scp: scp segue sempre i collegamenti simbolici (copia sempre il contenuto del file, ignorando i metadati tranne che -ppreserva i tempi e le modalità dei file quando possibile).

Se ti senti deluso da ciò che i metadati scp possono e non possono conservare, ti suggerisco di usare rsync. Senza alcuna opzione, rsync copia il contenuto del file ignorando i metadati. L'opzione comunemente usata -aconserva tutti i metadati della varietà del giardino (tempi, collegamenti simbolici, autorizzazioni e proprietà) e ci sono opzioni per preservare metadati esotici come ACL e hard link.


readlink esegue un solo passaggio per il collegamento in lettura. per esempio in Ubuntu abbiamo / bin / zsh, che è collegato a / etc / alternatives / zsh, ma questo è il secondo collegamento simbolico. Finalmente non avremo il percorso reale del file o della directory. Lo stesso è con il comando stat. Solo readlink con l'opzione -f risolve tutto.
Znik,

9

Io uso il comando ls, stat, readlink.

Prendi il file /etc/localtimecome esempio

[flying@lempstacker ~]$ ls /etc/localtime 
/etc/localtime
[flying@lempstacker ~]$ ls -l /etc/localtime
lrwxrwxrwx. 1 root root 35 Aug  2 22:41 /etc/localtime -> ../usr/share/zoneinfo/Asia/Shanghai

operazione

Usando stat

[flying@lempstacker ~]$ stat /etc/localtime
  File: ‘/etc/localtime’ -> ‘../usr/share/zoneinfo/Asia/Shanghai’
  Size: 35          Blocks: 0          IO Block: 4096   symbolic link
Device: fd01h/64769d    Inode: 272202388   Links: 1
Access: (0777/lrwxrwxrwx)  Uid: (    0/    root)   Gid: (    0/    root)
Access: 2016-11-23 09:00:59.999887800 +0800
Modify: 2016-08-02 22:41:26.090389904 +0800
Change: 2016-08-02 22:41:26.090389904 +0800
 Birth: -
[flying@lempstacker ~]$ stat -c "%N" /etc/localtime
‘/etc/localtime’ -> ‘../usr/share/zoneinfo/Asia/Shanghai’

Utilizzando readlink

[flying@lempstacker ~]$ readlink /etc/localtime
../usr/share/zoneinfo/Asia/Shanghai
[flying@lempstacker ~]$ readlink -f /etc/localtime
/usr/share/zoneinfo/Asia/Shanghai

Sembra che quel comando readlink -fsia migliore.

Spiegazione

-f, --canonicalizza: canonicalizza seguendo ricorsivamente ogni collegamento simbolico in ogni componente del nome dato; devono esistere tutti tranne l'ultimo componente —— Daman readlink


6

Stat ti fornirà queste informazioni:

$ stat current
  File: `current' -> `/home/user/releases/build/'
  ...

readlink esegue un solo passaggio per il collegamento in lettura. per esempio in Ubuntu abbiamo / bin / zsh, che è collegato a / etc / alternatives / zsh, ma questo è il secondo collegamento simbolico. Finalmente non avremo il percorso reale del file o della directory. Lo stesso è con il comando stat. Solo readlink con l'opzione -f risolve tutto.
Znik,

5

Puoi farlo entrambi

readlink -f `which command`

oppure puoi ottenere qualcosa di simile in Linux con

stat `which command` | grep File

Se lo stai aggiungendo a uno script, controlla l'errore. Se non vuoi vedere il messaggio di errore nel caso in cui il link sym non sia presente, scegli qualcosa di simile

readlink -f "`which command`" 

stat e realink senza -f fanno un solo passo. quindi meglio chiamare readlink -f.
Znik,

3

Vorrei usare realpath <symlink>.

Probabilmente quello che chiami "source" è il file "target" in base all'utilizzo di ln:Usage: ln [OPTION]... [-T] TARGET LINK_NAME


Grazie Questo ha funzionato come un fascino! con Mac OSX! dove readlinknon l'ho tagliato ... stupido mac. lol
JayRizzo,

0

readlink -f 'which java' non ha funzionato per me.

Ma questo ha fatto:

readlink -f $(which java)

3
Non ha funzionato perché è `non è '.. ma $()è meglio la pratica in ogni modo.
Stephen Rauch,

Perché votare? La mia risposta è un'alternativa accettabile e, come dice il commento, una pratica migliore.
NonCreature0714

1
La maggior parte delle persone che votano verso il basso non commentano, quindi chiedere una spiegazione di un voto negativo raramente ti darà una spiegazione, perché il votante verso il basso ha già lasciato e probabilmente non tornerà. Ti suggerirei di rimuovere il codice digitato che non funziona dalla tua risposta. Sarei disposto ad aumentare il voto se ti prendessi il tempo per ripulirlo e spiegare perché $()è una pratica migliore.
Stephen Rauch,

Come ti ha spiegato Stephen, "non è". Dovresti incapsulare per command, ma questo è deprecato. usare $ () è meglio, perché l'incapsulamento $ ($ (comando)) è molto più semplice e non necessita di escape speciali. Quindi è preferito. Nel tuo primo esempio hai usato il solito apostrofo, quindi readlink sta cercando di trovare il file chiamato 'quale java' con spazio nel suo nome. Ma hai intenzione di chiamare il comando che con argomento java, per trovare il percorso eseguibile binario java.
Znik,

0

Su MAC OX, il parametro "-f" non funziona, "readlink" funziona senza alcun parametro.

KZs-MacBook-Pro:bin kz$ readlink -f pip3
readlink: illegal option -- f
usage: readlink [-n] [file ...]

KZs-MacBook-Pro:bin kz$ readlink pip3
../../../Library/Frameworks/Python.framework/Versions/3.7/bin/pip3
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.