Wie erhalte ich den vollständigen Pfad der Originaldatei eines weichen symbolischen Links?

99

Ich möchte scpeine Datei auf einen Server. Die Datei ist ein symbolischer Link, und eigentlich möchte ich die Quelldatei kopieren. Auf jeden Fall möchte ich den Pfad der Quelldatei nicht manuell verfolgen, da er ersetzt werden kann. Wenn ich den absoluten Pfad der Quelldatei erhalten kann, kann ich das sepdamit tun. Wie komme ich zum Pfad?

Eonil
quelle
2
Die meisten scpVersionen folgen standardmäßig Symlinks, nicht wahr? Sie sollten Ihre überprüfen und sich vielleicht etwas Arbeit sparen.
jw013
@ jw103 Danke, dass du es mir mitgeteilt hast. Ich wusste es nicht. :)
Eonil
2
Hinweis: scp -rErzwingt das Folgen von Symlinks.
Eonil

Antworten:

129

Versuchen Sie diese Zeile:

readlink -f `which command`

Wenn commandin Ihrer $PATHVariablen enthalten ist, müssen Sie den Pfad angeben, den Sie kennen.

Gänseblümchen
quelle
12
-fgibt einen Pfad zu einem nicht existierenden Endziel zurück, solange die Zwischenverbindungsziele existieren ... Verwenden Sie -ediese Option , um dies zu vermeiden, d. h. -eGibt null zurück, wenn das endgültige Ziel nicht existiert.
Peter.O
10
-ffehler mit readlink: illegal option -- fin OSX. Das Entfernen hat gut funktioniert.
Heath Borders
2
@HeathBorders Für OSX, wenn Sie Homebrew-Coreutils installiert haben, können Sie greadlinkstattdessen auch verwenden .
Adam Gent
23

readlinkLiest unter Linux den Inhalt eines readlink -fSymlinks und folgt Symlinks zu Symlinks zu Symlinks usw., bis etwas gefunden wird, das kein Symlink ist.

Dies ist für scp jedoch nicht erforderlich: scp folgt immer Symlinks (kopiert immer den Dateiinhalt und ignoriert Metadaten, außer dass -pDateizeiten und -modi beibehalten werden, wenn dies möglich ist).

Wenn Sie enttäuscht sind, welche Metadaten scp beibehalten kann und welche nicht, empfehle ich die Verwendung von rsync. Ohne diese Option kopiert rsync den Dateiinhalt und ignoriert die Metadaten. Bei der häufig verwendeten Option werden -aalle Metadaten der Gartensorte (Zeiten, symbolische Verknüpfungen, Berechtigungen und Eigentumsrechte) beibehalten, und es gibt Optionen zum Beibehalten exotischer Metadaten wie ACLs und fester Verknüpfungen.

Gilles
quelle
readlink Führe nur einen einzigen Schritt für das Lesen des Links aus. In Ubuntu haben wir beispielsweise / bin / zsh, das mit / etc / alternatives / zsh verknüpft ist, aber dies ist der zweite Symlink. Schließlich erhalten wir keinen echten Datei- oder Verzeichnispfad. Das gleiche gilt für den Befehl stat. Nur readlink mit der Option -f löst alle auf.
Znik
9

Ich benutze Befehl ls, stat, readlink.

Nehmen Sie die Datei /etc/localtimeals Beispiel

[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

Betrieb

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

Mit Readlink

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

Dieser Befehl scheint readlink -fbesser zu sein.

Erläuterung

-f, --canonicalize: kanonisieren durch rekursives Folgen jedes Symlinks in jeder Komponente des angegebenen Namens; alle bis auf die letzte Komponente müssen vorhanden sein - Vonman readlink

Gorgon
quelle
6

Stat gibt Ihnen diese Informationen:

$ stat current
  File: `current' -> `/home/user/releases/build/'
  ...
Polynom
quelle
readlink Führe nur einen einzigen Schritt für das Lesen des Links aus. In Ubuntu haben wir beispielsweise / bin / zsh, das mit / etc / alternatives / zsh verknüpft ist, aber dies ist der zweite Symlink. Schließlich erhalten wir keinen echten Datei- oder Verzeichnispfad. Das gleiche gilt für den Befehl stat. Nur readlink mit der Option -f löst alle auf.
Znik
5

Sie können entweder tun

readlink -f `which command`

oder Sie können etwas Ähnliches in Linux mit bekommen

stat `which command` | grep File

Wenn Sie dies zu einem Skript hinzufügen, überprüfen Sie den Fehler. Wenn Sie die Fehlermeldung nicht sehen möchten, wenn der Sym-Link nicht vorhanden ist, gehen Sie zu etwas wie

readlink -f "`which command`" 
Alexandre Santos
quelle
stat und realink ohne -f machen nur einen Schritt. dann rufe besser readlink -f auf.
Znik
3

Ich würde verwenden realpath <symlink>.

Wahrscheinlich ist das, was Sie als "Quelle" bezeichnen, die "Zieldatei" gemäß der Verwendung von ln:Usage: ln [OPTION]... [-T] TARGET LINK_NAME

XavierStuvw
quelle
Danke Das hat wie ein Zauber funktioniert! mit Mac OSX! wo readlinkhat es nicht geschnitten ... dummer mac. lol
JayRizzo
0

readlink -f 'which java' hat bei mir nicht funktioniert.

Aber das tat:

readlink -f $(which java)
NonCreature0714
quelle
3
Hat nicht funktioniert, weil es `nicht ist '.. aber es $()ist sowieso besser zu üben.
Stephen Rauch
Warum abstimmen? Meine Antwort ist eine akzeptable Alternative und, wie der Kommentar sagt, eine bessere Praxis.
NonCreature0714
1
Die meisten Leute, die nicht abstimmen, kommentieren auch nicht. Wenn Sie nach einer Erklärung für eine Abwahl fragen, erhalten Sie selten eine Erklärung, da der Abwähler bereits abgereist ist und wahrscheinlich nicht wiederkommt. Ich würde vorschlagen, dass Sie den getippten Code, der nicht funktioniert, aus Ihrer Antwort entfernen. Ich würde gerne abstimmen, wenn Sie sich die Zeit nehmen und erklären würden, warum dies $()besser ist.
Stephen Rauch
Wie Stephen Ihnen erklärte, "ist nicht". Sie sollten durch kapseln command, aber dies ist veraltet. Die Verwendung von $ () ist besser, da die Kapselung von $ ($ (Befehl)) viel einfacher ist und kein spezielles Escapezeichen erfordert. Dann ist es bevorzugt. In Ihrem ersten Beispiel haben Sie den üblichen Apostroph verwendet und readlink versucht, eine Datei mit dem Namen 'which java' mit einem Leerzeichen im Namen zu finden. Aber Ihre Absicht ist es, den Befehl which mit dem Argument java aufzurufen, um den binären ausführbaren Pfad von java zu finden.
Znik
0

Unter MAC OX funktioniert der Parameter "-f" nicht, "readlink" funktioniert ohne Parameter.

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
Xb74Dkjb
quelle