Come elencare le catene a maglie simboliche?


Risposte:


65

Usa solo namei:

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

5
TIL. Questo è un bel comando. voti positivi
Tom O'Connor,

Questa dovrebbe essere la risposta accettata, in quanto mostra la catena completa di collegamenti come richiesto nell'op. Inoltre può essere usato per elencare un'intera directory simile a ls. Grazie!
fobico il

In effetti, stavo rivisitando questo post e namei è un comando meraviglioso!
Kalecser,

usare con il comando "which" per trovare l'effettivo utilizzo di un programma: $ namei` which java`
pdem

18

readlink -e <link>

readlink [OPZIONE] ... FILE

  • -e, --canonicalizza-
    canonicalizza -esistente seguendo ricorsivamente ogni collegamento simbolico in ogni componente del nome dato, tutti i componenti devono esistere
$ 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

nota: readlink a da solo restituisce b

nota # 2: insieme a find -l, un'utilità per elencare le catene potrebbe essere facilmente scritta in perl, ma deve anche essere abbastanza intelligente da rilevare loop

readlink non genererà nulla se si dispone di un loop. Questo è meglio che rimanere bloccati, suppongo.

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)

Su OS X: brew install coreutilsegreadlink -e <link>
Jose Alban,

3

Ecco una funzione ricorsiva 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; }

Su più righe:

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
}

Esempi:

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

Richiede stat(1)che potrebbe non essere presente su alcuni sistemi.

Fallirà se i nomi contengono backtick, virgolette singole o "->". Si blocca in un loop con loop symlink (questo potrebbe essere risolto usando un array associativo in Bash 4). Esporta una variabile chiamata "catena", indipendentemente dal fatto che sia già in uso.

Potrebbero esserci altri problemi con esso.

Modificare:

Risolto un problema con alcuni collegamenti simbolici relativi. Alcuni non funzionano ancora, ma la versione seguente non richiede l'esistenza del target del collegamento.

Aggiunta una versione che utilizza readlink:

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
}

Ho testato la tua sceneggiatura e funziona davvero, ma preferisco qualcosa di più semplice, quindi ho accettato l'altra risposta anche se incompleta.
Kalecser,

1
Bella sceneggiatura. A volte voglio vedere l'intera catena e readlinknon sembra dimostrarlo. Java su Ubuntu è:/usr/bin/java -> /etc/alternatives/java -> /usr/lib/jvm/java-6-openjdk/jre/bin/java
Stefan Lasiewski,

0

Puoi semplicemente postelaborare l'output di namei con qualcosa di simile awko grepper ottenere solo le righe che desideri:

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

o

namei d | egrep -e "->"
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.