Antworten:
Verwenden Sie die -f
Flagge, 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
brew install coreutils
. Dies installiert grundlegende Gnu-Versionen von Befehlen, denen der Buchstabe vorangestellt ist g
, dhgreadlink -f somefile
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."
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
Dies wird auch funktionieren:
ls -l /root/Public/myothertextfile.txt
aber readlink
würde für die Verwendung in einem Skript bevorzugt werden , anstatt das Parsen ls
.
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
-c
kann geschrieben werden --format
und %N
bedeutet "Dateiname in Anführungszeichen mit Dereferenzierung, wenn symbolischer Link".
Das readlink
ist 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 ls
Ausgabeformat.
Das Ergebnis von ls
kann auch innerhalb analysiert werden, bash
ohne von einem externen Befehl wie awk
, sed
oder abhängig zu sein perl
.
Diese bash_realpath
Funktion 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}"
}
Wenn Sie nicht verwenden können readlink
, können Sie das Ergebnis von ls -l
folgendermaß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
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
rwhich
Ist 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
Wenn Sie das Ziel aller Links innerhalb eines Ordners und seines Unterordners finden, verwenden Sie den find . -type l -ls
Befehl mit dem Linktyp wie folgt:
me@local.localdomain:~/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 -l
sollte das funktionieren:
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
readlink -f
.