Finden Sie das symbolische Linkziel über die Befehlszeile heraus

130

Angenommen, ich richte einen symbolischen Link ein:

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

Gibt es eine Möglichkeit zu sehen, was das Ziel der myothertextfile.txtVerwendung der Befehlszeile ist?

Jared
quelle

Antworten:

171

Verwenden Sie die -fFlagge, um die kanonisierte Version auszudrucken. Zum Beispiel:

readlink -f /root/Public/myothertextfile.txt

Von man readlink:

-f, --canonicalize
      canonicalize by following every symlink in every component of the given name recursively; all but the last component must exist
Brian-Brazil
quelle
8
Wie in einer anderen Frage vorgeschlagen , möchten Sie möglicherweise verwenden readlink -f.
Denilson Sá Maia
5
Um diese Arbeit auf Mac OS X, brew install coreutils. Dies installiert grundlegende Gnu-Versionen von Befehlen, denen der Buchstabe vorangestellt ist g, dhgreadlink -f somefile
Mike D
mit Schalter -f, gibt Befehl nichts in meinem Fall ..
SOTN
Mit -f habe ich die gewünschten Informationen erhalten, z. B. das Auflösen mehrerer Symlinks und das Anzeigen des Endziels.
Isapir
Auf Ubuntu 18.04.1 LTS (Bionic Beaver)den Hilfeseiten von readlink finden Sie eine Notiz mit der Aufschrift "Note realpath (1) ist der bevorzugte Befehl für die Kanonisierungsfunktion."
Sam Kamensky
23

readlink ist der gewünschte Befehl. Sie sollten sich die Manpage für den Befehl ansehen. Denn wenn Sie einer Kette symbolischer Verknüpfungen zur eigentlichen Datei folgen möchten, benötigen Sie den Schalter -e oder -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
Kyle Brandt
quelle
An der ersten Antwort ist nichts auszusetzen, aber diese ist vollständiger und hilfreicher.
Mike S
6

Dies wird auch funktionieren:

ls -l /root/Public/myothertextfile.txt

aber readlinkwürde für die Verwendung in einem Skript bevorzugt werden , anstatt das Parsen ls.

Dennis Williamson
quelle
4

Wenn Sie die Quelle und das Ziel des Links anzeigen möchten, versuchen Sie es stat -c%N files*. Z.B

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

Es ist nicht gut zum Parsen (dafür verwenden readlink), aber es zeigt den Linknamen und das Ziel an, ohne die Unordnung vonls -l

-ckann geschrieben werden --formatund %Nbedeutet "Dateiname in Anführungszeichen mit Dereferenzierung, wenn symbolischer Link".

Robert Siemer
quelle
2

Das readlinkist eine gute Sache, aber GNU-spezifisch und plattformunabhängig. Früher habe ich plattformübergreifende Skripte für geschrieben /bin/sh, daher würde ich Folgendes verwenden:

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

oder:

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

Diese müssen jedoch auf verschiedenen Plattformen getestet werden. Ich denke, sie werden funktionieren, aber nicht 100% sicher für das lsAusgabeformat.

Das Ergebnis von lskann auch innerhalb analysiert werden, bashohne von einem externen Befehl wie awk, sedoder abhängig zu sein perl.

Diese bash_realpathFunktion löst das endgültige Ziel eines Links auf (Link → Link → Link → Final):

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}"
}
Роман Коптев
quelle
1

Wenn Sie nicht verwenden können readlink, können Sie das Ergebnis von ls -lfolgendermaßen analysieren .

Das normale Ergebnis wäre:

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

Also wollen wir alles ersetzen, bevor "->" und der Pfeil enthalten sind. Wir könnten dafür verwenden sed:

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

Die Frage ist nicht genau genug, um eine einfache Antwort wie die von brian-brazil zu geben:

readlink -f some_path

wird in der Tat jeden Symlink dereferenzieren, der in das Pfadkonstrukt zum endgültigen Ziel dahinter involviert istsome_path .

Eine Ebene von kaskadierenden Symlinks ist jedoch nur ein besonderer Fall unter anderen in einem System, wobei der allgemeine Fall N Ebenen von kaskadierenden Symlinks ist. Schau dir folgendes auf meinem System an:

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

rwhichIst meine eigene rekursive Implementierung which, die alle zwischengeschalteten kaskadierenden Symlinks (zu stderr) bis zum endgültigen Ziel (zu stdout) ausgibt.

Wenn ich dann wissen will, was ist:

  • Das Ziel von symlink / usr / bin / emacs ** ist die offensichtliche Antwort für mich /etc/alternatives/emacs:

    readlink $(which emacs)
    readlink /usr/bin/emacs
    
  • Als endgültiges Ziel für die Kaskadierung von symlinks / usr / bin / emacs muss die Antwort lauten /usr/bin/emacs24-x:

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

lloder ls -lsollte die Verzeichniselemente einschließlich Ihres symbolischen Links und seines Ziels auflisten

cd -P /root/Public/myothertextfile.txt (In Ihrem Fall) sollte auf den ursprünglichen Pfad verweisen

Mantz
quelle
0

Wenn Sie das Ziel aller Links innerhalb eines Ordners und seines Unterordners finden, verwenden Sie den find . -type l -lsBefehl mit dem Linktyp wie folgt:

[email protected]:~/test$ find . -type l -ls
8601855888        0 lrwxr-xr-x    1 me           staff                   6 Jan 24 19:53 ./link -> target

Wenn du das Ziel einer Single haben willst, dann ls -lsollte das funktionieren:

[email protected]:~/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
Memin
quelle