なぜ `find` は `stat` や `fstat` を好むのでしょうか?

なぜ `find` は `stat` や `fstat` を好むのでしょうか?

/usr/bin/findを一切行わずに、何か意味のあるものを表示しようとしていますがstat、これまでのところ、有用な結果は得られていません。 を強制的に禁止するとstat、find はサブディレクトリへの下降をまったく停止します。

syscallのマニュアル ページにgetdents記載されているように、そこにはフィールドがあるd_typeため、find決定に必要な情報がすでにいくつかあるはずです。

stat、またはその他のオプションに関係なく-L、をなぜ必要とするのでしょうか-H

答え1

ソースを使いなさい、ルーク!

GNUfindソース (バージョン 4.2.2 を参照) では、ディレクトリ ツリーをトラバースするコードは にありますgnulib/lib/fts.c。1123 行目に次のコメントがあります。

fts_readがこのエントリに対して何をするかを記録します。多くの場合、fts_statが実行されますが、d_type情報を利用して不要なstat呼び出しを最適化できます。つまり、FTS_NOSTATが有効で、シンボリックリンクをたどっていない場合(FTS_PHYSICAL)、d_typeがこれを示している場合、ないディレクトリの場合は、statを実行する必要はまったくありません。ディレクトリの場合、デバイス番号と inode 番号を取得するために、(現時点では) とにかく stat を実行します。将来的には、d_ino が有効であることがわかっているディレクトリに対しても、これを最適化して削除するかもしれません。

つまり、彼らはあなたが説明した最適化を考えましたが、実装されていません。

答え2

引用したマニュアルページゲットデントLinux固有のものであり、すべてのファイルシステムタイプに適用されるわけではありません(たとえば、マニュアルページにはprocfsまたはnfs)、GNU探すプラットフォーム固有のものではありません(マニュアルページにはSELinuxについて記載されており、これは考慮する価値のある機能です)。できたこの特殊なケースにも最適化されます。

この機能が利用可能な場合でも、マニュアル ページでは次のことを推奨しています。

すべてのアプリケーションは、DT_UNKNOWN

つまり、利用可能な情報は役に立つ可能性がありますが、必ず存在するとは限りません。

これらすべての欠点があるため、開発者はfindこの最適化の必要性を感じないかもしれません。意欲のあるユーザーは、ソース コードを詳しく調べて、これを行う方法を確認し、適切な ifdef の変更を提案することができます。

@ネイト・エルドレッジ誰かが開始この方向へ。findマニュアルには7.2 d_typeの最適化

この機能を有効にすると、find は、一部のシステムでは readdir が struct dirent 内のファイルのタイプを返すという事実を利用します。

その特徴は最初に言及された

2005-01-17  James Youngman  <[email protected]>
    * configure.in, find/defs.h, find/find.c, find/parser.c, find/pred.c, find/tree.c, find/util.c:
    Implemented d_type optimisation but not working correctly, so currently disabled

その後、gnulibを使用するように修正これをサポートするには:

2010-04-08  James Youngman  <[email protected]>

    Adopt the use of the gnulib module d-type.
    * import-gnulib.config (modules): Import the d-type module.
    * configure.ac: Remove old struct dirent.d_type detection logic
    (since we now use the gnulib macro from the d-type module for
    this).

ちなみに、バージョン 4.2.2 はかなり古いです (おそらくタイプミスです)。4.2.32004年からのもので、これらの変更ログエントリより前のものです。gitの現在のリリースタグは4.5.14(2014年半ば)。

最適化の状態に関係なくd_type、開発者は の呼び出し回数を減らすことに関心がありますstat4.5.4(2009-03-10) では例えばこう言っています:

ftsfind 実行ファイルは、ディレクトリから既にこの情報を読み取っていれば、ファイルの inode 番号を見つけるために stat() 関数を呼び出すことも回避するようになりました。これにより速度が向上しますが、"find . -inum 4001" などの限られたコマンド セットに対してのみ有効です。この修正は、バグ #24342 として以下にリストされています。

要約: OPは尋ねた

-L、-H などのオプションに関係なく、なぜ for stat が必要なのでしょうか。

statその理由は、これが必要なすべてのシナリオではなく、シームレスに動作させるのが面倒な特殊なケースでありfind、これを行うには時間がかかるからです。

関連情報