Wie liste ich symbolische Gliederketten auf?


Antworten:


65

Verwenden Sie einfach namei:

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

5
Bis. Das ist ein cooler Befehl. Upvotes
Tom O'Connor

Dies sollte die akzeptierte Antwort sein, da sie die gesamte Kette von Links zeigt, wie sie in der Operation angefordert wurden. Außerdem kann es verwendet werden, um ein ganzes Verzeichnis ähnlich dem aufzulisten ls. Vielen Dank!
phobische

In der Tat war dieses Posting erneut und namei ist ein wunderbarer Befehl!
Kalecser

Verwenden Sie den Befehl "which", um die tatsächliche Verwendung eines Programms zu ermitteln: $ namei `which java`
pdem

18

readlink -e <link>

readlink [OPTION] ... DATEI

  • -e, --canonicalize-existing
    canonicalize, indem rekursiv jedem Symlink in jeder Komponente des angegebenen Namens gefolgt wird, 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 Dienstprogramm zum Auflisten der Ketten leicht in Perl geschrieben werden, muss aber auch intelligent genug sein, um Schleifen zu erkennen

readlink gibt nichts aus, wenn Sie eine Schleife haben. Das ist wohl besser als stecken zu bleiben.

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)

Unter OS X: brew install coreutilsundgreadlink -e <link>
Jose Alban

3

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 erfordert, stat(1)die auf einigen Systemen möglicherweise nicht vorhanden sind.

Es schlägt fehl, 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 kann andere Probleme damit geben.

Bearbeiten:

Ein Problem mit einigen relativen Symlinks wurde behoben. Einige funktionieren immer noch nicht, aber für die folgende Version muss das Ziel des Links nicht vorhanden sein.

Es wurde 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
}

Ich habe Ihr Skript getestet und es funktioniert wirklich, aber ich bevorzuge etwas Einfacheres, also habe ich die andere Antwort akzeptiert, auch wenn sie unvollständig ist.
Kalecser

1
Nettes Drehbuch. Manchmal möchte ich die gesamte Kette sehen und readlinkscheint das nicht zu zeigen. Java auf Ubuntu ist:/usr/bin/java -> /etc/alternatives/java -> /usr/lib/jvm/java-6-openjdk/jre/bin/java
Stefan Lasiewski

0

Sie könnten die Ausgabe von namei einfach mit etwas wie awkoder nachbearbeiten grep, um nur die gewünschten Zeilen zu erhalten:

namei d | awk '$1=="l"'

oder

namei d | egrep -e "->"
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.