回答:
タスクには使用しないことを強くお勧めfind -L
します(説明については以下を参照)。これを行う他の方法は次のとおりです。
「純粋なfind
」メソッドを使用する場合は、次のようになります。
find . -xtype l
(xtype
参照解除されたリンクで実行されるテストですfind
)ただし、これはのすべてのバージョンで利用できるわけではありません。しかし、他のオプションもあります:
コマンドtest -e
内から実行することもできますfind
:
find . -type l ! -exec test -e {} \; -print
いくつかのgrep
トリックでさえ、よりも優れている(つまり、より安全です)がfind -L
、質問(ファイル名を含む出力行全体を把握する)に示されているような正確なものではありません。
find . -type l -exec sh -c 'file -b "$1" | grep -q ^broken' sh {} \; -print
find -L
引用されたトリックソロでからCommandLineFuでは素晴らしく、ハックに見えますが、それは1つの非常に持っている危険な落とし穴を:すべてのシンボリックリンクが続いています。以下に示す内容のディレクトリを検討してください。
$ ls -l
total 0
lrwxrwxrwx 1 michal users 6 May 15 08:12 link_1 -> nonexistent1
lrwxrwxrwx 1 michal users 6 May 15 08:13 link_2 -> nonexistent2
lrwxrwxrwx 1 michal users 6 May 15 08:13 link_3 -> nonexistent3
lrwxrwxrwx 1 michal users 6 May 15 08:13 link_4 -> nonexistent4
lrwxrwxrwx 1 michal users 11 May 15 08:20 link_out -> /usr/share/
find -L . -type l
そのディレクトリで実行する場合、すべて/usr/share/
も検索されます(そして、それは本当に長い時間がかかる可能性があります)1。「発信リンクに耐性がある」コマンドの場合は、find
使用しないでください-L
。
1これはささいな不便さのように見えるかもしれません(コマンドはすべてを横断するのに「ちょうど」時間がかかります/usr/share
)-より深刻な結果をもたらす可能性があります。たとえば、chroot環境を考えてみましょう。これらはメインファイルシステムのサブディレクトリに存在し、絶対的な場所へのシンボリックリンクを含むことができます。これらのリンクは、「外部」システムでは壊れているように見える場合があります。これは、chrootに入ると適切な場所を指すだけだからです。また、一部のブートローダー/boot
は、ブートパーティションがとしてマウントされた最初のブートフェーズでのみ意味のあるシンボリックリンクを使用したことを思い出します/
。
したがって、find -L
コマンドを使用して、破損していないシンボリックリンクを無害なディレクトリから見つけて削除すると、システムが破損する可能性があります...
/proc/XXX/exe
リンクが壊れているかどうかを確認するためには機能しません。これには、を使用しますtest -e "$(readlink /proc/XXX/exe)"
。
find . -xtype l
は、「(最終)ターゲットファイルがシンボリックリンクであるすべてのシンボリックリンクを検索する」という意味です。しかし、シンボリックリンクの最終的なターゲットはシンボリックリンクにすることはできません。そうしないと、リンクをたどることができ、最終的なターゲットではありません。そのようなシンボリックリンクはないので、それらを別の何か、つまり壊れたシンボリックリンクとして定義できます。
l
ではなく、混乱が少なくなります。
-L
ハックには適用されず、壊れたシンボリックリンクを一般的に(ブラインドで)削除することに注意してください。
rozcietrzewiaczがすでにコメントしているようにfind -L
、検索をシンボリックリンクされたディレクトリに展開すると予期しない結果になる可能性があるため、最適なアプローチではありません。誰もまだ言及していないのは
find /path/to/search -xtype l
より簡潔で、論理的に同一のコマンドです
find /path/to/search -type l -xtype l
これまでに提示された解決策のいずれも、別のタイプの破損であるサイクリックシンボリックリンクを検出しません。 この質問は移植性に対処します。要約すると、循環リンクを含む壊れたシンボリックリンクを見つけるポータブルな方法は次のとおりです。
find /path/to/search -type l -exec test ! -e {} \; -print
詳細については、この質問またはynform.orgを参照してください。もちろん、これらすべての決定的なソースはfindutils documentatonです。
find -L
落とし穴と循環リンクに対処します。+1
-xtype
POSIXで指定し、あなたが見れば確かにされていないfind(1)
MacOSの中で、それは持っている-type
もののません -xtype
。
-L
コマンドにフラグを追加すると、grepを削除できると思います。
$ find -L . -type l
http://www.commandlinefu.com/commands/view/8260/find-broken-symlinks
男から:
-L Cause the file information and file type (see stat(2)) returned
for each symbolic link to be those of the file referenced by the
link, not the link itself. If the referenced file does not exist,
the file information and type will be for the link itself.
リンクが壊れているか周期的であるかにかかわらず、別の動作が必要な場合は、findで%Yを使用することもできます。
$ touch a
$ ln -s a b # link to existing target
$ ln -s c d # link to non-existing target
$ ln -s e e # link to itself
$ find . -type l -exec test ! -e {} \; -printf '%Y %p\n' \
| while read type link; do
case "$type" in
N) echo "do something with broken link $link" ;;
L) echo "do something with cyclic link $link" ;;
esac
done
do something with broken link ./d
do something with cyclic link ./e
この例は、この投稿(サイトが削除されました)からコピーされます。
参照
find
コマンドがサポートしていない人のためのさらに別の略記はxtype
、これから導き出すことができますfind . type l -printf "%Y %p\n" | grep -w '^N'
。アンディは彼のスクリプトで同じ(基本的な)アイデアで私を打ち負かしたので、私はそれを別の答えとして書くことに消極的でした。:)
これにより、現在のディレクトリにある壊れたシンボリックリンクの名前が出力されます。
for l in $(find . -type l); do cd $(dirname $l); if [ ! -e "$(readlink $(basename $l))" ]; then echo $l; fi; cd - > /dev/null; done
Bashで動作します。他のシェルについて知らない。
-type l
冗長だと思います。だから、おそらくあなたが必要とするすべてです。このアプローチをありがとう。-xtype l
-type l
find -xtype l