Soluzione 1:
Basta usare namei
:
$ namei d
f: d
l d -> c
l c -> b
l b -> a
d a
Soluzione 2:
readlink -e <link>
readlink [OPZIONE]... FILE
- -e, --canonicalize-esistente
canonicalize seguendo ogni collegamento simbolico in ogni componente del nome dato in modo ricorsivo, tutti i componenti devono esistere
$ mkdir testlink
$ cd testlink
[email protected]:~/testlink$ ln -s c b
[email protected]:~/testlink$ ln -s b a
[email protected]:~/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
[email protected]:~/testlink$ echo foo > c
[email protected]:~/testlink$ cat a
foo
[email protected]:~/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 i loop
readlink non produrrà nulla se hai un ciclo. Questo è meglio che rimanere bloccati, suppongo.
[email protected]:~/testlink$ ln -sf a c
[email protected]:~/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
[email protected]:~/testlink$ readlink -e a
[email protected]:~/testlink$ # (note: no output)
Soluzione 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 apici inversi, virgolette singole o "->". Si blocca in un ciclo con cicli di collegamenti simbolici (questo potrebbe essere risolto utilizzando un array associativo in Bash 4). Esporta una variabile chiamata "chain" indipendentemente dal fatto che sia già in uso.
Potrebbero esserci altri problemi con esso.
Modifica:
Risolto un problema con alcuni collegamenti simbolici relativi. Alcuni continuano a non funzionare, ma la versione seguente non richiede l'esistenza della destinazione 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
}