Étant donné cet exemple:
mkdir a
ln -s a b
ln -s b c
ln -s c d
Si j'exécute:
ls -l d
Il montrera:
d -> c
Existe-t-il un moyen pour ls
ou toute autre commande linux d'afficher à la d -> c -> b -> a
place?
Étant donné cet exemple:
mkdir a
ln -s a b
ln -s b c
ln -s c d
Si j'exécute:
ls -l d
Il montrera:
d -> c
Existe-t-il un moyen pour ls
ou toute autre commande linux d'afficher à la d -> c -> b -> a
place?
Réponses:
Il suffit d'utiliser namei
:
$ namei d
f: d
l d -> c
l c -> b
l b -> a
d a
ls
. Merci!
readlink -e <link>
readlink [OPTION] ... FILE
- -e, --canonicalize-
canonicalize existant en suivant chaque lien symbolique dans chaque composant du nom donné de manière récursive, tous les composants doivent exister
$ 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
note: readlink a par lui-même retourne b
note n ° 2: avec find -l, un utilitaire permettant de répertorier les chaînes pourrait facilement être écrit en perl, mais doit également être suffisamment intelligent pour détecter les boucles
readlink ne produira rien si vous avez une boucle. C'est mieux que de rester coincé, je suppose.
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)
brew install coreutils
etgreadlink -e <link>
Voici une fonction récursive dans 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; }
Sur plusieurs lignes:
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
}
Exemples:
$ chain d
d -> c -> b -> a
$ chain c
c -> b -> a
$ chain a
a
Cela nécessite stat(1)
ce qui peut ne pas être présent sur certains systèmes.
Il échouera si les noms contiennent des backticks, des guillemets simples ou "->". Il se bloque dans une boucle avec des boucles de liens symboliques (ceci pourrait être résolu en utilisant un tableau associatif dans Bash 4). Il exporte une variable appelée "chaîne", qu'elle soit déjà utilisée ou non.
Il peut y avoir d'autres problèmes avec cela.
Modifier:
Correction d'un problème avec certains liens symboliques relatifs. Certains ne fonctionnent toujours pas, mais la version ci-dessous n'exige pas que la cible du lien existe.
Ajout d'une version qui utilise 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
}
readlink
ne semble pas le montrer. Java sur Ubuntu est:/usr/bin/java -> /etc/alternatives/java -> /usr/lib/jvm/java-6-openjdk/jre/bin/java