1. 概要

このチュートリアルでは、さまざまな形式でfindコマンドを使用して壊れたシンボリックリンクを見つける方法を説明します。

2. シンボリックリンク

シンボリックリンク、シンボリックリンク、またはソフトリンクは、他のリンク、ファイル、ディレクトリ、およびリソースを指すファイルです。 これらは、Windowsのショートカットに似ています。

これらはリンクであるため、ターゲットが使用できなくなると、使用できなくなります。

この例は、次のディレクトリ構造で実行されます。

上記の環境を再現するために、空のディレクトリで次のコマンドを実行できます。

mkdir -p baeldung/dir-1/dir-2/dir-3/
touch baeldung/file.txt
touch baeldung/dir-1/file-1.txt
touch baeldung/dir-1/dir-2/file-2.txt
touch baeldung/dir-1/dir-2/dir-3/file-3.txt
ln -s dir-2/dir-3/ baeldung/dir-1/dir-3
ln -s ../../file-1.txt baeldung/dir-1/dir-2/dir-3/file-1.txt
ln -s baeldung/nonexistent-directory baeldung/dir-1/dir-2/link-to-nonexistent-directory
ln -s dir-4/file-4.txt baeldung/dir-1/dir-2/dir-3/file-4.txt
ln -s dir-2/file-2.txt baeldung/dir-1/file-2.txt
ln -s ../filex.txt baeldung/dir-1/filex.txt
ln -s ../cyclic-link baeldung/dir-1/cyclic-link
ln -s dir-1/cyclic-link baeldung/cyclic-link
ln -s . baeldung/infinite-loop

3. 壊れたシンボリックリンクを見つける

findコマンドの構造は次のとおりです。

find [-H] [-L] [-P] [-D debugopts] [-Olevel] [starting-point...] [expression]

-H、-L、および-Pオプションは、シンボリックリンクの処理方法を制御します。 省略した場合は、デフォルトとして-Pを使用します

-P が使用され、 find がシンボリックリンクからの情報を調べたり印刷したりする場合、詳細はシンボリックリンク自体のプロパティから取得されます。

コマンドにはBashシェルを想定します。

3.1. 簡単な方法

壊れたシンボリックリンクを検出する最も簡単な方法は、次のコマンドを使用することです。

find baeldung -xtype l

私たちの環境で上記のコマンドを実行すると、次の出力が生成されます。

find: ‘baeldung/cyclic-link’: Too many levels of symbolic links
find: ‘baeldung/dir-1/cyclic-link’: Too many levels of symbolic links
baeldung/dir-1/filex.txt
baeldung/dir-1/dir-2/link-to-nonexistent-directory
baeldung/dir-1/dir-2/dir-3/file-4.txt

最初の2行で、壊れたシンボリックリンクを検出しているだけでなく、サイクリックリンクも報告していることがわかります。サイクリックリンクの後に、壊れたリンクが表示されます。

-xtype l引数を使用しました。これは、壊れたシンボリックリンクにのみ当てはまります。

-P フラグを含めることで、同じことを達成できたはずです。

find baeldung -P -xtype l

ご想像のとおり、これは-Pがデフォルトのであることを意味します。

3.2. ポータブルウェイ

POSIX準拠のシェルの場合、-xtypeがすべてのシステムで使用できるとは限らないため、以下のソリューションを使用できます

find baeldung -type l ! -exec test -e {} \; -print

予想どおり、出力は最後のサンプルと同じになります。

baeldung/cyclic-link
baeldung/dir-1/cyclic-link
baeldung/dir-1/filex.txt
baeldung/dir-1/dir-2/link-to-nonexistent-directory
baeldung/dir-1/dir-2/dir-3/file-4.txt

ここで何が起こっているのかを部分的に分けてみましょう。

  • find コマンドは、前のサンプルで行ったのと同じ方法で、リンクタイプのファイルを探します。
  • は、ファイルの存在をテストしている– exec 式の結果を否定しています–否定すると、存在しないファイルのみが表示されます
  • exec 式アクションは、見つかった各ファイルのコマンドを実行するために使用されます。 この場合、ファイルごとに test-eを実行しています。 test は、ファイルタイプの確認と値の比較に使用されるLinuxコマンドです。 -e 引数を使用して、ファイルが存在するかどうかを確認しています
  • {}は現在のファイル名に置き換えられます
  • \ は、シェルによる拡張からコマンドを保護するために使用されます–コマンドは、「\」の使用を避けるために引用符で囲むことができます
  • ;はコマンドの終わりを表します
  • -printは結果を標準出力に出力します

3.3. ポータブルで詳細な方法

または、この標準ソリューションは多くのWebサイトで見つけることができます。

find -L baeldung -type l

実際、上記の他のソリューションよりもうまく機能します。 これは、2行目にあるように、「ファイルシステムループ」も報告するためです。

find: ‘baeldung/cyclic-link’: Too many levels of symbolic links
find: File system loop detected; ‘baeldung/infinite-loop’ is part of the same file system loop as ‘baeldung’
find: ‘baeldung/dir-1/cyclic-link’: Too many levels of symbolic links
baeldung/dir-1/dir-3/file-4.txt
baeldung/dir-1/filex.txt
baeldung/dir-1/dir-2/link-to-nonexistent-directory
baeldung/dir-1/dir-2/dir-3/file-4.txt

多くの人が知らない副作用は、リンクがディレクトリを指している場合、このアプローチが詳細な検索を行うことです。

たとえば、 / usr /shareを指すリンクがあるとします。 -L オプションを使用すると、find/usr /share構造全体をトラバースします。

このアプローチを完了するには、時間とリソースがかかりすぎる可能性があります。 ほとんどの場合、それは私たちがやろうとしていることではありません。 それぞれのアプローチをいつ使用するかを知り、その利点と結果を念頭に置くことが不可欠です。

したがって、ディレクトリを指すリンクがあるときにディレクトリ内の壊れたリンクを検索する場合は、-Lオプションを使用できます。

ただし、特定のディレクトリ構造内にとどまり、リンクをたどりたくない場合は、-Lを使用する必要はありません。

この違いを確認するために、デバッグを有効にして、アクセスした各ファイルとフォルダーを表示できます。

find -D search baeldung -xtype l
find -D search -L baeldung -type l

3.4. ハッキーウェイ

ユーザー権限レベルを使用してファイルを読み取る別のアプローチを使用できます。

壊れたリンクと、読み取り権限のないファイルが表示されるため、少しハックです。 つまり、このオプションは実際にはrootユーザーにのみ適用できます。

そうは言っても、以下のコマンドを使用して、壊れたリンクを見つけることができます

find baeldung -type l ! -readable

これにより、最後のサンプルと同様の出力が生成されます。

baeldung/cyclic-link
baeldung/dir-1/cyclic-link
baeldung/dir-1/filex.txt
baeldung/dir-1/dir-2/link-to-nonexistent-directory
baeldung/dir-1/dir-2/dir-3/file-4.txt

この場合、シンボリックリンクタイプのファイルを検索する -type lを使用しました。

次に、 -読み取り可能との引数 !。 これにより、読み取れないファイルが表示されます。

壊れたリンクは読み取れないため、結果の一部として返されます。

3.5. 範囲と深さを制限する

いくつかの便利なテスト式を使用して、検索の範囲を制限できます。

  • lname pattern :リンク名パターンを提供できます
  • ilname pattern lname と同じですが、大文字と小文字は区別されません
  • maxdepth :このディレクトリの深さまで検索します
  • mindepth :このディレクトリの深さから検索

例として、次を実行できます。

find baeldung -mindepth 3 -ilname "*.TXT" -xtype l

これは出力を生成します:

baeldung/dir-1/dir-2/dir-3/file-4.txt

3.6. 出力のカスタマイズ

出力をカスタマイズして、より有用な情報を提供できます。

式アクション-ls、を使用すると、リンクとそれが指す場所に関する詳細情報を取得できます。

find baeldung -xtype l -ls

そして、出力は次のようになります。

find: ‘baeldung/cyclic-link’: Too many levels of symbolic links
find: ‘baeldung/dir-1/cyclic-link’: Too many levels of symbolic links
 21109100      0 lrwxrwxrwx   1  fabio    fabio          12 Sep 17 23:26 baeldung/dir-1/filex.txt -> ../filex.txt
 21109086      0 lrwxrwxrwx   1  fabio    fabio          30 Sep 17 23:21 baeldung/dir-1/dir-2/link-to-nonexistent-directory -> baeldung/nonexistent-directory
 21109087      0 lrwxrwxrwx   1  fabio    fabio          16 Sep 17 23:21 baeldung/dir-1/dir-2/dir-3/file-4.txt -> dir-4/file-4.txt

このアプローチは、ファイル名が異常なの場合はうまく機能しません。これは、 \0/以外の任意の文字を含めることができ、改行も含まれるためです。

ファイル名に異常な文字が含まれていると、端末に予期しない、多くの場合望ましくないことが発生する可能性があります。 たとえば、特定の文字は、一部の端末のファンクションキーの設定を変更できます。

4. 結論

この簡単な記事では、単純でより複雑なアプローチを使用して壊れたリンクを見つける方法、検索の範囲を制限する方法、および出力をカスタマイズする方法について説明しました。

findユーティリティは本物のスイスアーミーナイフです!詳細については、findmanページをご覧ください。