Linux

為什麼我的 find -type d 對文件夾中的每個文件都執行 fstat?

  • October 25, 2014

find . -type d在一個相當大的目錄樹上執行。我只對在這棵樹中查找目錄感興趣,但是當我對程序執行 strace 以確保它正在做我期望它做的事情時,我注意到有大量的操作被浪費在對文件執行 fstat樹內。

newfstatat(AT_FDCWD, "file1", {st_mode=S_IFREG|0600, st_size=7690, ...}, AT_SYMLINK_NOFOLLOW) = 0
newfstatat(AT_FDCWD, "file2", {st_mode=S_IFREG|0600, st_size=7696, ...}, AT_SYMLINK_NOFOLLOW) = 0
newfstatat(AT_FDCWD, "file3", {st_mode=S_IFREG|0600, st_size=7687, ...}, AT_SYMLINK_NOFOLLOW) = 0
newfstatat(AT_FDCWD, "file4", {st_mode=S_IFREG|0600, st_size=10455, ...}, AT_SYMLINK_NOFOLLOW) = 0

find 在執行 fstat 之前是否不知道 inode 指向目錄?如果是這種情況,那麼這將需要很長時間。其中一些目錄可能包含數百萬個項目,但我真的只關心目錄。

最終,我想要一份關於我的文件樹中每個目錄的 dirsize 和路徑的報告。對我來說最快/最有效的方法是什麼?

是的,看起來確實是 find 使用fstat來確定文件的類型。鑑於dirent包含自核心 2.6.4 以來的資訊,這有點令人驚訝。

並非所有文件系統都支持擴展的 dirent 行為,因此在您的情況下這是正確的,或者 find 不使用它。在不知道您的文件系統類型的情況下,我們無法決定。

我相信您知道,目錄是 UNIX 範例中的一種特殊類型的文件。要確定某個東西是目錄還是其他類型的文件,必須對其進行詢問,而 fstat() 是一個很好的方法。

我相信後來的文件系統和 fs-drivers 保留了一個單獨的目錄表,但是 find 命令可以追溯到幾十年前,並且可能不適應較新的文件系統或者它保持向下兼容性。

您可以通過在 CRON 之外執行重複性作業來偽造這一點(如果您想輕鬆地使用其他程序的 IO 使用率,則使用一個不錯的值 >0)執行以下操作:

查找 ${DIRECTORY} -type d -print >${DIRECTORY}/.only_folders

然後,當您需要它時,請使用您預先建構的文件的內容,而不是再次遍歷目錄。

cat "${DIRECTORY}/.only_folders" |同時讀取文件夾;做
do_work.sh ${文件夾} ;
完畢

而不是像

查找 ${DIRECTORY} -type d |xargs do_work.sh

引用自:https://serverfault.com/questions/639575