私は頻繁に他の場所にディレクトリツリーを移動したり、他のマシンに自分のtarballをコピーし、私は、ディレクトリツリー内のすべてのシンボリックリンクかどうかを確認する方法がしたいAのの場所の外部にポイントAをこれらが移動/コピーに分割されますので、ディレクトリ。
私は頻繁に他の場所にディレクトリツリーを移動したり、他のマシンに自分のtarballをコピーし、私は、ディレクトリツリー内のすべてのシンボリックリンクかどうかを確認する方法がしたいAのの場所の外部にポイントAをこれらが移動/コピーに分割されますので、ディレクトリ。
回答:
realpath
と組み合わせて使用すると呼ばれるプログラムが必要ですfind
。
例えば:
find . -type l -exec realpath {} \; | grep -v "^$(pwd)"
bindfsを使用して、そのディレクトリツリーの別のビューを作成します。
mkdir /tmp/view
bindfs /some/directory /tmp/view
次に、symlinksユーティリティ(多くのディストリビューションに同梱されているか、sourceからコンパイル)を使用して、ファイルシステム間のリンクを検出します。
symlinks -r /tmp/view | sed -n 's/^\(absolute\|other_fs\): //p'
(出力の解析では、シンボリックリンクとそのターゲットに改行が含まれていないこと、およびシンボリックリンクへのパスに部分文字列が含まれていないことを前提としています ->
。)同じユーティリティで絶対シンボリックリンクを相対リンクに変換することもできます(ただし、元の場所)。
zshの場合:
cd -P -- "$dir"
for i (**/*(ND@)) [[ $i:A = $PWD/* ]] || [[ $i:A = $PWD ]] || print -r -- "$i => $i:A"
ここで、ディレクトリが/foo
あり、それが/foo/bar
へのシンボリックリンクである/foo/baz
場合、それは/ fooにターゲットがあるリンクですが、いったん移動すると、リンクは依然として壊れます。そのため、シンボリックリンクを絶対パスに一致させることもできます。
しかし、それでも、bar => ../foo/baz
in /foo
は問題(偽陰性)であり、a => b
where b
はツリー外のシンボリックリンク(偽陽性、見方によって異なります)になります。
私はそれを機能させるために@bahamatによって与えられた答えを少し微調整する必要がありました。
提供されたバージョンは、問題の絶対位置を報告するだけで、それを指すシンボリックリンクは報告しませんでした。
これが私が使ったものです(改善できると確信しています):
for f in $(find . -type l ); do echo -n $(realpath $f) && echo -n "|" && echo $f ; done | grep -v "^$(pwd)" | cut -d \| -f 2
for f in $(find . -type l); do echo $(realpath -m -q $f) '<-' $f; done | grep-v "^$(pwd)"
特に-m
、-q
壊れたリンクと外部以外のリンクを除外します)
GNU coreutilsはrealpath
、シンボリックリンクを解決するを証明します。これにより、各シンボリックリンクのターゲットを現在の作業ディレクトリと比較することができます。
#!/bin/bash
find . | while read filename
do
if realpath $filename | grep -E "^$PWD" > /dev/null
then
echo 'this file is safe'
else
echo 'this file links externally'
fi
done
-type l
、なし-r
のオプションはread
、のためにサニタイズないIFS read
、$filename
引用符で囲まれていない、$PWD
正規表現として扱われ、改行文字とパスが占めていない、/foobar
のために一致するだろう$PWD
==「/ foo」という