findが時々コマンドラインパス引数と一致するのはなぜですか?

findが時々コマンドラインパス引数と一致するのはなぜですか?

Linuxでは、

cd /tmp
mkdir foo; cd foo

今実行

find . -name 'foo'

出力がありません。走っている間

find /tmp/foo -name 'foo'

与えられた出力は/tmp/foo私には理解できません。誰かが理由を説明できますか?

答え1

find指定されたディレクトリツリーに移動し、見つかったファイルごとに指定された式を評価します。巡回は指定されたパスから始まります。仕組みをまとめると、次のようになりますfind . -name foo

  • コマンドラインの最初のパス:.
    • basename(.)がパターンと一致していますかfoo?いいえ、だから何もしないでください。
      これは/tmp/foo同じディレクトリの別の名前です。しかし、findそれを知りません(知ろうと努力してはいけません)。
    • パスはディレクトリですか?はい、繰り返し見てください。リスト内の項目を列挙.し、各項目に対して反復処理を実行します。
      • ディレクトリは空です。および.その他の項目は含まれておらず、再帰的には検索されません。そして作業が完了しました。..find

そしてfind /tmp/foo

  • コマンドラインの最初のパス:/tmp/foo
    • basename(foo)がパターンと一致していますかfoo?はい、条件が満たされました。
      • この条件に関連するジョブがないため、パスを印刷する基本ジョブが実行されます。
    • パスはディレクトリですか?はい、繰り返し見てください。リスト内の項目を列挙/tmp/fooし、各項目に対して反復処理を実行します。
      • ディレクトリは空です。および.その他の項目は含まれておらず、再帰的には検索されません。そして作業が完了しました。..find

.とは/tmp/foo同じディレクトリですが、find同じ動作を保証するのに十分ではありません。このfindコマンドには、同じファイルへのパスを区別する方法があり、-nameその1つが述部です。find /tmp/foo -name foo開始ディレクトリとその下に指定されたすべてのエントリと一致しますfoofind . -name .開始ディレクトリのみが一致します(.再帰巡回中には見つかりません)。

答え2

テストが適用されるまで、コマンドラインパラメータは標準化されていません。したがって、結果は使用されているパスによって異なります(シンボリックリンクが含まれている場合)。

cd /tmp
mkdir foo
ln -s foo bar
find /tmp/foo -name foo
find /tmp/bar -name foo

「あなたの場合」では、両方の呼び出しは同じ結果を提供するので(もっと)混乱する可能性があります。-mindepth 1始点(POSIXではない可能性があります)を無視したい場合に使用できます。

答え3

(gnu)findはコマンドライン引数の比較を開始し、そこからディレクトリ構造にドリルダウンすると、コマンドに指定されたパスで見つかった一致を表示します(したがって、-maxdepth 0テストを基本レベルまたはコマンドライン引数に制限するだけですが、説明これが-mindepth 1コマンドライン引数をスキップします。man findfind /tmp/foo -name 'foo'

find . -name 'foo'一方、.(dot)は同じinodeへのハードリンクのように動作する特別なファイルなので、何も生成されません/tmp/foo。これは、シンボリックリンクまたは制限された式シェルのパス名拡張子ではなく、別々の(特殊ですが)ファイル名と同じです。したがって、与えられた例では、コマンドライン引数にfindを介して適用された最初のテストでは、.実際に定義された名前パターンと一致するものがないため、一致するものは表示されません-name 'foo'/tmp/foo/.パターンテストは-nameパスの基本名に対してのみ行われるため(参考資料を参照man find)、そうではありません.

この動作はユーザーの観点から予想されたり直観的ではないかもしれませんが(例えば最初は私も混乱していました)、これはバグを構成しませんが、マニュアルと情報ページに記載されているものと一致します。論理的および機能的対応(gnu)照会。

答え4

foo相対検索を開始したディレクトリに指定されたオブジェクトはありません。

開始ディレクトリとして絶対名を使用するときに報告するときにgfind問題があると仮定します。/tmp/foo

Gfind標準とのすべての偏差のために他の標準を見つけたようです。sfindこれをにお勧めしますschilytools

-nameディレクトリ検索結果に適用されます。上記のいずれの場合も、タスクはfooディレクトリエントリを返しません。readdir()

関連情報