Solución 1:
Solo usa namei
:
$ namei d
f: d
l d -> c
l c -> b
l b -> a
d a
Solución 2:
readlink -e <link>
enlace de lectura [OPCIÓN]... ARCHIVO
- -e, --canonicalize-existente
canonicalice siguiendo cada enlace simbólico en cada componente del nombre dado de forma recursiva, todos los componentes deben existir
$ 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 por sí solo devuelve b
nota #2:junto con find -l, una utilidad para enumerar las cadenas podría escribirse fácilmente en perl, pero también debe ser lo suficientemente inteligente como para detectar bucles
readlink no generará nada si tiene un bucle. Esto es mejor que quedarse atascado, supongo.
[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)
Solución 3:
Aquí hay una función recursiva en 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; }
En varias líneas:
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
}
Ejemplos:
$ chain d
d -> c -> b -> a
$ chain c
c -> b -> a
$ chain a
a
Requiere stat(1)
que puede no estar presente en algunos sistemas.
Fallará si los nombres contienen acentos graves, comillas simples o "->". Se atasca en un bucle con bucles de enlaces simbólicos (esto podría resolverse usando una matriz asociativa en Bash 4). Exporta una variable llamada "cadena" sin importar si ya está en uso.
Puede haber otros problemas con él.
Editar:
Se solucionó un problema con algunos enlaces simbólicos relativos. Algunos todavía no funcionan, pero la versión a continuación no requiere que exista el destino del enlace.
Se agregó una versión que usa enlace de lectura:
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
}