この例を考えると:
mkdir a
ln -s a b
ln -s b c
ln -s c d
私が実行すると:
ls -l d
表示されます:
d -> c
代わりにls
または他のLinuxコマンドがd -> c -> b -> a
を表示する方法はありますか?
namei
を使用するだけです:
$ namei d
f: d
l d -> c
l c -> b
l b -> a
d a
readlink -e <link>
readlink [オプション] ...ファイル
- -e、-canonicalize-existing
指定された名前のすべてのコンポーネントのすべてのシンボリックリンクを再帰的にたどることによって正規化し、すべてのコンポーネントが存在している必要があります
$ 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
注:readlink a自体はbを返します
注2:チェーンを一覧表示するユーティリティは、find -lと一緒にPerlで簡単に作成できますが、ループを検出するのに十分スマートでなければなりません。
ループがある場合、readlinkは何も出力しません。これは行き詰まるよりはましだと思います。
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)
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; }
_
複数行で:
_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
}
_
例:
_$ chain d
d -> c -> b -> a
$ chain c
c -> b -> a
$ chain a
a
_
一部のシステムには存在しないstat(1)
が必要です。
名前にバッククォート、一重引用符、または "->"が含まれていると失敗します。これは、symlinkループのあるループでスタックします(これは、Bash 4の連想配列を使用して解決できます)。すでに使用されているかどうかに関係なく、「チェーン」と呼ばれる変数をエクスポートします。
その他の問題がある可能性があります。
編集:
いくつかの相対シンボリックリンクの問題を修正しました。一部はまだ機能しませんが、以下のバージョンではリンクのターゲットが存在する必要はありません。
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
}
_
Nameiの出力をawk
やgrep
などで後処理して、必要な行だけを取得できます。
namei d | awk '$1=="l"'
または
namei d | egrep -e "->"