Назад | Перейти на главную страницу

Почему мой 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? Если это так, то это займет много времени. В некоторых из этих каталогов, вероятно, есть миллионы элементов, но на самом деле меня интересуют только каталоги.

В конечном итоге я хотел бы получить отчет о размере каталога и пути каждого из каталогов в моем дереве файлов. Какой для меня самый быстрый / эффективный способ сделать это?

Да, похоже, что это действительно тот случай, когда find использует fstat чтобы определить тип файла. Это немного удивительно, учитывая, что ужасный содержит информацию, начиная с ядра 2.6.4.

Не все файловые системы поддерживают расширенное поведение dirent, поэтому либо это верно в вашем случае, либо find его не использует. Мы не можем решить, не зная тип вашей файловой системы.

Как я уверен, вы знаете, что каталог - это особый тип файла в парадигме UNIX. Чтобы определить, является ли что-то каталогом или файлом другого типа, его нужно запросить, и fstat () - хороший способ сделать это.

Я считаю, что более поздние файловые системы и fs-драйверы хранят отдельную таблицу только для каталогов, но команда find существует несколько десятилетий назад и, вероятно, либо не адаптирована к новым файловым системам, либо поддерживает обратную совместимость.

Вы можете подделать это, запустив повторяющееся задание из CRON (при хорошем значении> 0, если вы хотите упростить использование ввода-вывода для других процессов), которое выполняет:

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

Затем, когда вам это нужно, используйте содержимое предварительно созданного файла вместо повторного обхода каталога.

cat "${DIRECTORY}/.only_folders" |while read FOLDER ; do
  do_work.sh ${FOLDER} ;
done

вместо чего-то вроде

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