40 votos

Cómo enumerar enlace simbólico cadenas?

Dado este ejemplo:

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

Si yo ejecuto:

ls -l d

Se mostrará:

d -> c

Hay una manera para ls o cualquier otro linux comando para mostrar d -> c -> b -> a lugar?

77voto

Mike Puntos 221

sólo uso namei:

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

20voto

Paul Puntos 1066

hombre readlink

Se puede hacer la siguiente parte con la opción-e

$ 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 una de por sí, se devuelve b

nota #2: junto con encontrar-l, una utilidad a la lista de cadenas que fácilmente podría ser escrito en perl, pero también tiene que ser lo suficientemente inteligente como para detectar bucles

readlink no sacará nada si tienes un loop. Esto es mejor que quedarse atascado, supongo.

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)

4voto

jason saldo Puntos 5036

Aquí es 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

Se requiere stat(1) que puede no estar presente en algunos sistemas.

Se producirá un error si los nombres de contener comillas simples inclinadas, comillas simples, o "->". Se queda atascado en un bucle con el enlace de bucles (esto podría ser resuelto mediante un array asociativo en Bash 4). Exporta una variable llamada "cadena", sin tener en cuenta si ya está en uso.

Puede haber otros problemas con ella.

Editar:

Se ha corregido un problema con algunos relativa de los enlaces simbólicos. Algunos aún así no funciona, pero la versión que a continuación no requieren el destino del vínculo que existe.

Añadido una versión que utiliza 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
}

EnMiMaquinaFunciona.com

EnMiMaquinaFunciona es una comunidad de administradores de sistemas en la que puedes resolver tus problemas y dudas.
Puedes consultar las preguntas de otros sysadmin, hacer tus propias preguntas o resolver las de los demás.

Powered by: