为什么我的 find -type d 对文件夹中的每个文件执行 fstat?

为什么我的 find -type d 对文件夹中的每个文件执行 fstat?

我正在一个相当大的目录树上运行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 指向目录?如果是这样,那么这将需要很长时间。其中一些目录可能包含数百万个项目,但我真的只关心目录。

最后,我希望得到文件树中每个目录的大小和路径的报告。对我来说,最快/最有效的方法是什么?

答案1

是的,看起来 find 确实在使用状态统计确定文件的类型。这有点令人惊讶,因为直接自内核2.6.4以来就包含了该信息。

并非所有文件系统都支持扩展的 dirent 行为,因此,要么这对您而言是正确的,要么 find 不使用它。如果不知道您的文件系统类型,我们就无法决定。

答案2

我相信您知道,目录是 UNIX 范例中一种特殊类型的文件。要确定某个对象是目录还是其他类型的文件,必须对其进行查询,而 fstat() 就是一个很好的方法。

我相信后来的文件系统和 fs 驱动程序会保留一个仅包含目录的单独表,但是 find 命令可以追溯到几十年前,并且可能无法适应较新的文件系统,或者它保持向下兼容性。

你可以通过运行 CRON 中的重复作业来伪造这一点(如果你想要轻松利用其他进程的 IO,则可以使用 >0 的值),该作业执行以下操作:

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

然后,当您需要它时,使用预先构建的文件的内容,而不是再次遍历目录。

cat "${DIRECTORY}/.only_folders" |同时读取 FOLDER ; 执行
  执行工作.sh ${FOLDER};
完毕

而不是像

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

相关内容