Frage Wie listet man symbolische Linkketten auf?


Bei diesem Beispiel:

mkdir a
ln -s a b
ln -s b c
ln -s c d

Wenn ich folgendes ausführe:

ls -l d

Wird sich zeigen:

d -> c

Gibt es einen Weg dafür? ls oder irgendeinen anderen Linux-Befehl, der angezeigt werden soll d -> c -> b -> a stattdessen?


30
2018-02-23 16:23


Ursprung


Ich übersetze dies als stackoverflow.com/questions/2320277/ ...  Ich hoffe, es macht dir nichts aus. - Paul


Antworten:


Benutz einfach namei:

$ namei d
f: d
 l d -> c
   l c -> b
     l b -> a
       d a

56
2017-11-22 10:03



TIL. Das ist ein cool Befehl. upvotes - Tom O'Connor
Dies sollte die akzeptierte Antwort sein, da es die vollständige Kette von Links zeigt, wie in der Op. Weiter kann es verwendet werden, um ein ganzes Verzeichnis ähnlich wie bei ls. Vielen Dank! - phobic
In der Tat, war wieder auf diesen Beitrag und Name ist ein wunderbares Kommando! - Kalecser
Verwenden Sie mit "which" Befehl, um die tatsächliche Verwendung eines Programms zu finden: $ namej `which java` - pdem


readlink -e <link>

readlink [OPTION] ... DATEI

  • -e, - kanonisieren-vorhanden
      canonicalize Wenn Sie jeden Symlink in jeder Komponente des angegebenen Namens rekursiv verfolgen, müssen alle Komponenten existieren
$ mkdir testlink
$ cd testlink
pjb@pjb-desktop:~/testlink$ ln -s c b
pjb@pjb-desktop:~/testlink$ ln -s b a
pjb@pjb-desktop:~/testlink$ ls -l 
total 0
lrwxrwxrwx 1 pjb pjb 1 2010-02-23 08:48 a -> b
lrwxrwxrwx 1 pjb pjb 1 2010-02-23 08:48 b -> c
pjb@pjb-desktop:~/testlink$ echo foo > c
pjb@pjb-desktop:~/testlink$ cat a
foo
pjb@pjb-desktop:~/testlink$ readlink -e a
/home/pjb/testlink/c

hinweis: readlink a selbst gibt b zurück

note # 2: zusammen mit find -l kann ein programm zum auflisten der ketten einfach in perl geschrieben werden, aber auch schlau genug sein, um schleifen zu erkennen

readlink gibt nichts aus, wenn Sie eine Schleife haben. Das ist besser als steckenbleiben, nehme ich an.

pjb@pjb-desktop:~/testlink$ ln -sf a c
pjb@pjb-desktop:~/testlink$ ls -l 
total 0
lrwxrwxrwx 1 pjb pjb 1 2010-02-23 08:48 a -> b
lrwxrwxrwx 1 pjb pjb 1 2010-02-23 08:48 b -> c
lrwxrwxrwx 1 pjb pjb 1 2010-02-23 09:03 c -> a
pjb@pjb-desktop:~/testlink$ readlink -e a
pjb@pjb-desktop:~/testlink$ # (note: no output)

16
2018-02-23 16:51



Unter OS X: brew install coreutils und greadlink -e <link> - Jose Alban


Hier ist eine rekursive Funktion in Bash:

chain() { export chain; local link target; if [[ -z $chain ]]; then chain="$1"; fi; link=$(stat --printf=%N $1); while [[ $link =~ \-\> ]]; do target="${link##*\`}"; target="${target%\'}"; chain+=" -> $target"; chain "$target"; return; done; echo "$chain"; unset chain; }

In mehreren Zeilen:

chain() {
    export chain
    local link target
    if [[ -z $chain ]]
    then
        chain="$1"
    fi
    link=$(stat --printf=%N "$1")
    while [[ $link =~ \-\> ]]
    do
        target="${link##*\`}"
        target="${target%\'}"
        chain+=" -> $target"
        if [[ ! $target =~ / && $1 =~ / ]]
        then
            target="${1%/*}/$target"
        fi
        chain "$target"
        return
    done
    echo "$chain"
    unset chain
}

Beispiele:

$ chain d
d -> c -> b -> a
$ chain c
c -> b -> a
$ chain a
a

Es benötigt stat(1) welches auf einigen Systemen nicht vorhanden sein kann.

Es wird fehlschlagen, wenn Namen Backticks, einfache Anführungszeichen oder "->" enthalten. Es bleibt in einer Schleife mit Symlink-Schleifen stecken (dies könnte mit einem assoziativen Array in Bash 4 gelöst werden). Es exportiert eine Variable namens "chain" unabhängig davon, ob sie bereits verwendet wird.

Es könnte andere Probleme geben.

Bearbeiten:

Ein Problem mit einigen relativen symbolischen Links wurde behoben. Einige funktionieren immer noch nicht, aber die folgende Version erfordert nicht, dass das Ziel der Verknüpfung vorhanden ist.

Eine Version hinzugefügt, die readlink verwendet:

chain ()
{
    export chain;
    local target;
    if [[ -z $chain ]]; then
        chain="$1";
    fi;
    target=$(readlink "$1");
    while [[ $target ]]; do
        chain+=" -> $target";
        if [[ ! $target =~ / && $1 =~ / ]]
        then
            target="${1%/*}/$target"
        fi
        chain "$target";
        return;
    done;
    echo "$chain";
    unset chain
}

3
2018-02-23 17:34



Ich habe dein Skript getestet und es funktioniert wirklich, aber ich bevorzuge etwas einfacher, also habe ich die andere Antwort akzeptiert, auch wenn sie unvollständig ist. - Kalecser
Nettes Skript. Manchmal möchte ich die gesamte Kette sehen, und readlink scheint das nicht zu zeigen. Java unter Ubuntu ist: /usr/bin/java -> /etc/alternatives/java -> /usr/lib/jvm/java-6-openjdk/jre/bin/java - Stefan Lasiewski