なぜ find は期待される結果を返さないのか?解決策はこちら!

Unixベースのシステムで find コマンドを実行したことがある方なら、ファイルが確実に存在するにもかかわらず、コマンドがそれらを見つけられないというフラストレーションを感じたことがあるかもしれません。たとえば、シェルスクリプトファイルを検索しようとした場合、存在していると確信していても、出力は空であることがあります。この一般的な問題は、find コマンドがワイルドカード文字をどのように解釈するかに関する誤解から生じることが多いです。問題の詳細を掘り下げ、検索を正しく行うための解決策を見つけていきましょう。

問題:find が期待どおりに動作しない

以下のようなコマンドを試したかもしれません:

$ find /usr -name *.sh

このコマンドは、/usr ディレクトリ内のすべての .sh 拡張子を持つファイルを検索することを意図しています。しかし、結果が表示されない場合、なぜ find は動作しないのか? と疑問に思うかもしれません。

スクリプトがそこにあることは確信しています;たとえば、次のように実行すると:

$ ls /usr/local/lib/*.sh

tclConfig.shtkConfig.sh などのファイルが見えるはずです。それでは、あなたの find コマンドには何が問題なのでしょうか?

問題の理解

ここでの主な問題は、コマンドシェルがワイルドカード *.sh をどのように解釈するかです。特に、現在のディレクトリに *.sh に一致するファイルが存在する場合、シェルは find が作用する前にそのワイルドカードを展開します。これにより予期しない動作が発生することがあります:

  1. ワイルドカードの展開

    • 現在のディレクトリに .sh ファイル(例えば、tkConfig.sh)が存在する場合、find /usr -name *.sh と入力すると、これは find /usr -name tkConfig.sh に展開され、実質的に検索対象をそのファイルのみに制限してしまいます。
  2. 構文エラー

    • 複数のファイルが一致する場合、find があいまいな引数のために構文エラーをスローすることがあります:
      find: bad option tkConfig.sh
      

解決策1:ワイルドカードの引用

シェルがワイルドカードを展開するのを防ぐために、ワイルドカード文字を引用することができます:

  • ダブルクォーテーションを使用する場合:
    $ find /usr -name "*.sh"
    
  • シングルクォーテーションを使用する場合:
    $ find /usr -name '*.sh'
    

*.sh を引用することで、シェルにそのまま find に渡すよう指示しており、指定されたディレクトリ内のすべての .sh ファイルを検索できるようになります。

解決策2:シンボリックリンクを追う

find が期待どおりに動作しない別の理由は、/usr ディレクトリまたはそのサブディレクトリ内にシンボリックリンクが存在することです。デフォルトでは、find はシンボリックリンクを追跡しません。これが原因かもしれないと疑う場合、-follow オプションを使用できます:

$ find /usr -follow -name '*.sh'

このコマンドを使用すると、find はシンボリックリンクをたどり、目的のファイルを検索します。

結論

要約すると、find コマンドがシェルスクリプトを検索して期待される結果を出さない場合、ワイルドカードの展開またはシンボリックリンクの存在が原因である可能性があります。ワイルドカードの早期展開を防ぐために、引用を行うことを常に忘れず、必要に応じて -follow オプションを使用してください。これらの戦略を採用することで、シェルスクリプトを問題なく見つけ、コマンドラインの熟練度を高めることができます!

ハッピーサーチング!

これで、自信を持って find コマンドに取り組む準備が整いました!質問やさらなる問題があれば、コメントで気軽にお知らせください。