Jak uzyskać pełną ścieżkę oryginalnego pliku miękkiego linku symbolicznego?


99

Chcę scpplik na serwer. Plik jest dowiązaniem symbolicznym, a tak naprawdę to, co chcę zrobić, to skopiować plik źródłowy. W każdym razie nie chcę ręcznie śledzić ścieżki pliku źródłowego, ponieważ można go zastąpić. Jeśli mogę uzyskać ścieżkę bezwzględną do pliku źródłowego, mogę to sepzrobić. Jak mogę uzyskać ścieżkę?


2
Większość scpwersji domyślnie korzysta z dowiązań symbolicznych, prawda? Powinieneś sprawdzić swoją i być może zaoszczędzić trochę pracy.
jw013,

@ jw103 Dziękujemy za poinformowanie mnie o tym. Nie wiedziałem :)
Eonil,

2
Uwaga: scp -rwymusza podążanie za dowiązaniami symbolicznymi.
Eonil,

Odpowiedzi:


129

Wypróbuj tę linię:

readlink -f `which command`

Jeśli commandznajduje się w $PATHzmiennej, w przeciwnym razie musisz podać ścieżkę, którą znasz.


12
-fzwróci ścieżkę do nieistniejącego celu końcowego, o ile istnieją pośrednie cele docelowe ... Użyj, -eaby tego uniknąć, tj. -ezwróci null, jeśli ostateczny cel nie istnieje.
Peter.O,

10
-fbłędnie z readlink: illegal option -- fw OSX. Usunięcie działało dobrze.
Heath Borders

2
@HeathBorders Dla OSX, jeśli masz zainstalowany rdzeń domowy, możesz także użyć greadlinkzamiast tego.
Adam Gent,

23

Pod Linuksem readlinkodczytuje zawartość dowiązania symbolicznego i readlink -fpodąża za dowiązaniami symbolicznymi do dowiązań symbolicznych itp., Aż znajdzie coś, co nie jest dowiązaniem symbolicznym.

Nie jest to jednak konieczne w przypadku scp: scp zawsze podąża za dowiązaniami symbolicznymi (zawsze kopiuje zawartość pliku, ignorując metadane, z wyjątkiem tego, że -pzachowuje czasy i tryby plików, jeśli to możliwe).

Jeśli jesteś rozczarowany tym, co metadane scp może, a czego nie może zachować, sugeruję użycie rsync. Bez opcji rsync kopiuje zawartość pliku ignorując metadane. Często używana opcja -azachowuje wszystkie metadane z różnych odmian ogrodu (czasy, dowiązania symboliczne, uprawnienia i własność), a istnieją opcje zachowania egzotycznych metadanych, takich jak listy ACL i twarde linki.


readlink robi tylko jeden krok do linkowania do odczytu. na przykład w Ubuntu mamy / bin / zsh, który jest symlinkowany do / etc / alternatives / zsh, ale to jest drugie symlink. Wreszcie nie otrzymamy prawdziwej ścieżki do pliku lub katalogu. To samo dotyczy polecenia stat. Tylko readlink z opcją -f rozwiązuje wszystkie problemy.
Znik

9

Używam polecenia ls, stat, readlink.

Weź plik /etc/localtimejako przykład

[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

Operacja

Korzystanie ze statystyki

[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’

Korzystanie z readlink

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

Wygląda na to, że readlink -fto polecenie jest lepsze.

Wyjaśnienie

-f, --canonicalize: kanonizuje przez rekursywne śledzenie każdego dowiązania symbolicznego w każdym składniku podanej nazwy; wszystkie oprócz ostatniego składnika muszą istnieć —— Odman readlink


6

Stat poda następujące informacje:

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

readlink robi tylko jeden krok do linkowania do odczytu. na przykład w Ubuntu mamy / bin / zsh, który jest symlinkowany do / etc / alternatives / zsh, ale to jest drugie symlink. Wreszcie nie otrzymamy prawdziwej ścieżki do pliku lub katalogu. To samo dotyczy polecenia stat. Tylko readlink z opcją -f rozwiązuje wszystkie problemy.
Znik

5

Możesz albo

readlink -f `which command`

lub możesz uzyskać coś podobnego w Linuksie

stat `which command` | grep File

Jeśli dodajesz to do skryptu, sprawdź błąd. Jeśli nie chcesz wyświetlać komunikatu o błędzie w przypadku, gdy nie ma łącza sym, wybierz coś takiego

readlink -f "`which command`" 

stat i realink bez -f wykonują tylko jeden krok. lepiej zadzwoń do readlink -f.
Znik

3

Chciałbym użyć realpath <symlink>.

Prawdopodobnie to, co nazywacie „źródłem”, to plik „docelowy”, zgodnie z zastosowaniem ln:Usage: ln [OPTION]... [-T] TARGET LINK_NAME


Dzięki To działało jak urok! z Mac OSX! gdzie readlinkgo nie wyciąłem ... głupi Mac. lol
JayRizzo

0

readlink -f 'which java' nie działało dla mnie.

Ale to zrobiło:

readlink -f $(which java)

3
Nie działa, ponieważ jest `nie '.. ale $()jest lepsza praktyka jakikolwiek.
Stephen Rauch

Dlaczego głosować? Moja odpowiedź jest akceptowalną alternatywą i, jak mówi komentarz, lepszą praktyką.
NonCreature0714,

1
Większość osób, które głosowały w dół, nie komentują, więc prośba o wyjaśnienie głosowania w dół rzadko daje ci wyjaśnienie, ponieważ głosujący w głosowaniu już odszedł i prawdopodobnie nie wróci. Sugeruję usunięcie kodu literowego, który nie działa z twojej odpowiedzi. Byłbym skłonny do głosowania, gdybyś poświęcił czas na jego oczyszczenie i wyjaśnienie, dlaczego $()lepsza praktyka.
Stephen Rauch,

Jak wyjaśnił ci Stephen, „nie jest”. Powinieneś enkapsulować przez command, ale to jest przestarzałe. użycie $ () jest lepsze, ponieważ enkapsulacja $ ($ (polecenie)) jest znacznie łatwiejsza i nie wymaga specjalnego ucieczki. To jest preferowane. W pierwszym przykładzie użyłeś zwykłego apostrofu, a następnie readlink próbuje znaleźć plik o nazwie „która java” ze spacją w nazwie. Ale twoją intencją jest polecenie wywołania, które z argumentem java, w celu znalezienia binarnej ścieżki wykonywalnej java.
Znik

0

W MAC OX parametr „-f” nie działa, „readlink” działa bez żadnego parametru.

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
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.