Почему моя находка - тип 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

Не знает находка, что inode указывает на каталог, пока это не выполняет fstat? Если это так, затем это собирается занять много времени. Некоторые из этих каталогов, вероятно, имеют миллионы объектов в них, но я действительно только забочусь о каталогах.

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

3
задан 25 October 2014 в 10:13
2 ответа

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

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

4
ответ дан 3 December 2019 в 05:42

Я уверен, что вы знаете, что каталог - это особый тип файла в парадигме 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
1
ответ дан 3 December 2019 в 05:42

Теги

Похожие вопросы