我正在一个相当大的目录树上运行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
答案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