シンボリックリンクの切れたファイルを探す
今回、ESXi サーバーの導入に伴い、既存の NetBSD サーバーを ESXi ゲストに移行したのですが、その際、あまり参照していないディレクトリに「リンクの切れたシンボリックリンク」が大量に残っているのを発見しました。こいつをまとめて削除しようと思ったのですが、方法が分からず、しばし途方に暮れました。
あるパス名が「リンクの切れたシンボリックリンク」かどうかを確認する方法で、すぐに思いつくのは ls -FL コマンドを使う方法です。例えばここに file_a, symlink_a, symlink_b というパス群があり、symlink_a はリンク先があるが、symlink_b はリンク先が失われているものとしましょう。ls -FL を実行すると、次のようになります。
$ ln -FL file_a symlink_a symlink_b@
-L オプションを付けているにも関わらず、末尾に「@」が表示されるのは、リンクの切れたシンボリックリンクです。しかし、これを find コマンドの自動処理に応用するのは面倒ですし*1、エレガントとは言えません。きっと、何かもっとうまい方法があるはずだ! というわけで、少し調べてみました。
最初は、type*2 や stat コマンドとか探したのですが、解は見つかりません。その後、test コマンドで解決できることが分かりました。例えば find コマンドで、リンクの切れたシンボリックを一覧するには、次のようにします。(-r でなく、-e を使うのが重要です。)
$ find . -exec test -h {} -a \! -e {} \; -print
うまく行っている感じではありますが、盲点がないかどうか、もう少し検証してみようと思います。