Почему `find` так похож на `stat` или `fstat`?

Почему `find` так похож на `stat` или `fstat`?

Я пытаюсь сделать, /usr/bin/findчтобы показать что-то значимое, не делая ничего stat, пока без каких-либо полезных результатов. Если я принудительно подавляю stat, find останавливает спуск в подкаталоги вообще.

Как getdentsсказано в руководстве по системному вызову, d_typeтам есть поле, поэтому findуже должна быть некоторая информация, необходимая для принятия решений.

Зачем это нужно, statнезависимо от того -L, -Hили какие-либо другие варианты.

решение1

Используй источник, Люк!

В исходном коде GNU find(я рассматриваю версию 4.2.2) код, который обходит деревья каталогов, находится в gnulib/lib/fts.c. В строке 1123 есть следующий комментарий:

Запишите, что fts_read будет делать с этой записью. Во многих случаях он просто fts_stat ее, но мы можем воспользоваться любой информацией d_type, чтобы оптимизировать ненужные вызовы stat. То есть, если FTS_NOSTAT действует и мы не следуем символическим ссылкам (FTS_PHYSICAL) и d_type указывает, что этонеткаталог, то нам вообще не придется его stat. Если этоявляетсякаталог, то (в настоящее время) мы stat его независимо, чтобы получить номера устройств и инодов. Когда-нибудь мы могли бы оптимизировать это также для каталогов, где d_ino заведомо является допустимым.

Поэтому они задумались об оптимизации, которую вы описываете, но она не реализована.

решение2

Цитируемая страница руководства дляgetdentsотносится только к Linux и не применяется ко всем типам файловых систем (например, на странице руководства не упоминаетсяprocfsилиnfs), в то время как GNUнаходитьне зависит от платформы (на его странице руководства упоминается SELinux, что, возможно, является полезной функцией, которую следует учитывать).могбыть оптимизированы и для этого особого случая.

Даже если функция доступна, на странице руководства рекомендуется:

Все приложения должны правильно обрабатывать возвратDT_UNKNOWN.

То есть информация, если она доступна, может быть полезной, но ее наличие не гарантируется.

При всех этих недостатках разработчики findмогут не видеть необходимости в этой оптимизации. Мотивированный пользователь может углубиться в исходный код, чтобы посмотреть, как это сделать, и предложить подходящее изменение ifdef.

@Нейт Элдриджотмечает, что кто-тоначалв этом направлении. findВ руководстве говорится, что7.2 Оптимизация d_type

Если эта функция включена, find использует тот факт, что в некоторых системах readdir возвращает тип файла в struct dirent.

Особенность была в том, чтопервое упоминаниев

2005-01-17  James Youngman  <[email protected]>
    * configure.in, find/defs.h, find/find.c, find/parser.c, find/pred.c, find/tree.c, find/util.c:
    Implemented d_type optimisation but not working correctly, so currently disabled

Позже это былопереработано для использования gnulibв поддержку этого:

2010-04-08  James Youngman  <[email protected]>

    Adopt the use of the gnulib module d-type.
    * import-gnulib.config (modules): Import the d-type module.
    * configure.ac: Remove old struct dirent.d_type detection logic
    (since we now use the gnulib macro from the d-type module for
    this).

Кстати, версия 4.2.2 довольно старая (возможно, опечатка):4.2.3датируется 2004 годом и предшествует этим записям в журнале изменений. Текущий релиз-тег в git —4.5.14(середина 2014 г.).

Независимо от статуса оптимизации d_type, разработчики заинтересованы в уменьшении количества вызовов stat. Примечание от4.5.4(2009-03-10) говорит, например:

Исполняемый файл ftsfind теперь также избегает вызова функций stat() для обнаружения номера inode файла, если мы уже считываем эту информацию из каталога. Это обеспечивает ускорение, но только для ограниченного набора команд, таких как "find . -inum 4001". Это исправление указано ниже как ошибка #24342.

Вкратце: ОП спросил

Зачем это нужно для статистики независимо от -L, -H или каких-либо других опций.

Причина в том, что это особый случай, который сложно заставить работать бесперебойно, а не statдля всех сценариев, где findэто может потребоваться, и на это требуется время.

Связанный контент