為什麼「find」如此喜歡「stat」或「fstat」?

為什麼「find」如此喜歡「stat」或「fstat」?

我試圖/usr/bin/find在不做任何事情的情況下展示一些有意義的東西stat,到目前為止還沒有任何有用的結果。如果我強行抑制stat, find 根本不會降到子目錄。

正如係統呼叫手冊頁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 指示這是不是一個目錄,那麼我們根本不需要統計它。如果它目錄,然後(當前)我們無論如何都要對其進行統計,以便取得設備和索引節點號。有一天,我們可能也會針對已知 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.3日期可以追溯到 2004 年,並且早於這些變更日誌條目。 git 中目前的發布標籤是4.5.14(2014 年中)。

無論優化的狀態如何d_type,開發人員都對減少對stat.來自的註釋4.5.4(2009-03-10) 例如說:

如果我們已經從目錄中讀取了此信息,則 ftsfind 可執行檔現在還可以避免調用 stat() 函數來發現檔案的索引節點號。這確實提供了加速,但僅限於有限的命令集,例如“find . -inum 4001”。此修復在下面列出為 bug #24342。

總結:OP問

為什麼需要統計數據而不管 -L、-H 或任何選項。

原因是它是一種特殊情況,使其無縫工作很麻煩,而不是stat適用於所有find可能需要它的場景,並且需要時間來做到這一點。

相關內容