найти против найти: использование, плюсы и минусы друг друга

Ответы:

166

locate(1)имеет только одно большое преимущество перед find(1): скорость.

find(1)Тем не менее, имеет много преимуществ по сравнению с locate(1):

  • find(1)изначально, возвращаясь к самой первой версии AT & T Unix . Вы даже найдете его в урезанных встроенных Linux-системах через Busybox . Это все, кроме универсального.

    locate(1)намного моложе чем find(1). Самый ранний предок locate(1) не появлялся до 1983 года , и он не был широко доступен как " locate" до 1994 года, когда он был принят в GNU findutils и в 4.4BSD .

  • locate(1)также является нестандартным , поэтому он не устанавливается по умолчанию везде. Некоторые операционные системы типа POSIX даже не предлагают его в качестве опции, и там, где он доступен, реализации может не хватать требуемых функций, поскольку нет независимого стандарта, определяющего минимальный набор функций, который должен быть доступен.

    Существует де - факто стандарт, BSDlocate(1) , но это только потому , что другие два основных вкус locateреализовать все свои варианты: -0, -c, -d, -i, -l, -m, -s, и -S. mlocateреализует 6 дополнительных опций не в BSD locate: -b, -e, -P, -q, --regexи -w. GNUlocate реализует эти шесть плюс еще четыре : -A, -D, -E, и -p. (Я игнорирую псевдонимы и незначительные различия , как -?против -hпротив --help.)

    BSD и Mac OS X поставляются с BSD locate.

    Большинство Linux поставляются с GNU locate, но mlocateвместо этого поставляются Red Hat Linux и Arch . Debian не устанавливается ни в своей базовой установке, но предлагает обе версии в своих репозиториях пакетов по умолчанию; если оба установлены сразу, " locate" запускается mlocate.

    Oracle поставляется mlocateв Solaris с 11.2 , выпущенной в декабре 2014 года. До этого locateон не был установлен по умолчанию в Solaris. (Предположительно, это было сделано для уменьшения несовместимости команд Solaris с Oracle Linux , который основан на Red Hat Enterprise Linux , который также использует mlocate.)

    IBM AIX по- прежнему не поставляется ни с какой версией locate, по крайней мере, с AIX 7.2 , если вы не установите GNU findutilsиз AIX Toolbox для приложений Linux .

    HP-UX также появляется на отсутствие locateв базовой системе.

    Старые "настоящие" Unixes обычно не включали реализацию locate.

  • find(1)имеет мощный синтаксис выражений со многими функциями, логическими операторами и т. д.

  • find(1)Можно выбирать файлы не только по имени. Он может выбрать по:

    • возраст
    • размер
    • владелец
    • тип файла
    • отметка времени
    • разрешений
    • глубина в поддереве ...
  • При поиске файлов по имени вы можете выполнять поиск, используя синтаксис глобализации файлов во всех версиях find(1)или в версиях GNU или BSD, используя регулярные выражения .

    Текущие версии locate(1)принимают шаблоны glob, как это findделает, но BSD locateвообще не выполняет регулярные выражения. Если вы похожи на меня и должны использовать различные типы машин, вы предпочитаете grepфильтрацию, а не развитие зависимости от -rили --regex.

    locateнуждается в сильной фильтрации больше, чем findпотому что ...

  • find(1)не обязательно искать всю файловую систему. Обычно вы указываете его в подкаталог, родительский файл, содержащий все файлы, с которыми вы хотите работать. Типичное поведение для locate(1)реализации состоит в том, чтобы извергать все файлы, соответствующие вашему шаблону, оставляя его для grepфильтрации и тому подобного, чтобы сократить его извержение до размера.

    (Злой совет: locate /вероятно, вы получите список всех файлов в системе!)

    Существуют варианты, locate(1)например, slocate(1)которые ограничивают вывод на основе разрешений пользователя, но это не версия по умолчанию locateв любой основной операционной системе.

  • find(1)может делать что-то с файлами, которые он находит, в дополнение к их поиску. Самый мощный и широко поддерживаемый такой оператор есть -exec, но есть и другие. В последнее время GNU и BSD найти реализации, например, у вас есть -deleteи -execdirоператоры.

  • find(1) работает в режиме реального времени, поэтому его вывод всегда актуален.

    Поскольку locate(1)база данных обновляется часами или днями ранее, ее вывод может быть устаревшим. (Это проблема устаревшего кэша .) Эта монета имеет две стороны:

    1. locate можно назвать файлы, которые больше не существуют.

      GNU locateи mlocateимеет -eфлаг, чтобы он проверял существование файла перед печатью имени каждого файла, который он обнаружил в прошлом, но это лишает некоторых locateпреимуществ в скорости и, locateкроме того, недоступно в BSD .

    2. locate не сможет назвать файлы, которые были созданы с момента последнего обновления базы данных.

    Вы учитесь быть недоверчивым к locateвыводу, зная, что это может быть неправильно.

    Есть способы решить эту проблему, но я не знаю ни о какой реализации в широком использовании. Например, есть rlocate, но, похоже, не работает против любого современного ядра Linux.

  • find(1) никогда не имеет больше привилегий, чем пользователь, управляющий им.

    Поскольку locateпредоставляет глобальный сервис всем пользователям в системе, он хочет, чтобы его updatedbпроцесс запускался так, rootчтобы он мог видеть всю файловую систему. Это приводит к выбору проблем безопасности:

    1. Запустите updatedbот имени пользователя root, но сделайте его выходной файл доступным для чтения всем пользователям, чтобы он locateмог работать без особых привилегий. Это эффективно раскрывает имена всех файлов в системе для всех пользователей. Этого может быть достаточно для нарушения безопасности, чтобы вызвать реальную проблему.

      BSD locateнастроен таким образом на Mac OS X и FreeBSD.

    2. Записать базу данных как доступную только для чтения rootи сделать locate setuidroot, чтобы она могла читать базу данных. Это означает, что locateфактически необходимо переопределить систему разрешений ОС, чтобы она не показывала файлы, которые вы обычно не видите. Это также увеличивает поверхность атаки вашей системы, особенно рискуя атакой с эскалацией корней .

    3. Создайте специального " locate" пользователя или группу для владения файлом базы данных и отметьте locateдвоичный файл как setuid/setgidдля этого пользователя / группы, чтобы он мог читать базу данных. Это не предотвращает атаки на повышение привилегий само по себе, но значительно уменьшает ущерб, который можно нанести.

      mlocateнастроен таким образом в Red Hat Enterprise Linux .

      У вас все еще есть проблема, потому что, если вы можете использовать отладчик locateили заставить его выгружать ядро, вы можете получить доступ к привилегированным частям базы данных.

    Я не вижу способа создать действительно «безопасную» locateкоманду, если не выполнять ее отдельно для каждого пользователя в системе, что сводит на нет большую часть ее преимуществ перед find(1).

Итог, оба очень полезны. locate(1)лучше, когда вы просто пытаетесь найти определенный файл по имени, который, как вы знаете, существует, но вы просто не помните, где он находится. find(1)лучше, когда у вас есть сфокусированная область для исследования, или когда вам нужно какое-либо из ее многочисленных преимуществ.

Уоррен Янг
источник
Извините, я пропустил абзац "slocate". rlocate решает проблему устаревшего кэша . Возможно, вы захотите упомянуть некоторые из особенностей поиска, например, find -- "$dir" ненадежность ( $dirможно принять за предикат), отсутствие способа проверить атрибуты символической ссылки, проблемы состояния гонки ... Для меня findи locateрешить две разные проблемы. Есть много мест, где использование поиска нереально (например, каталоги, содержащие миллионы файлов). locate - это система индексирования, ограниченная именами файлов.
Стефан Шазелас
2
Первые реализации locateбыли примерно чем-то похожи find / -type f | gzip > locate.gz, иzgrep "$1" <locate.gz
Ф. Хаури
@ F.Hauri: Интересные мелочи. Вот еще: GNU locateнаходится в findutilsпакете, и его updatedbпрограмма реализована в терминах find(1). Так что в этом смысле locate(1)действительно требуется find(1) . :)
Уоррен Янг
1
@WarrenYoung почему постоянная ссылка на foo (1) вместо просто foo? Существуют ли разные версии и т. д. Foo?
Сумасшедший о Natty
4
@nuttyaboutnatty: Это древнее соглашение в руководствах по Unix, означающее раздел руководства 1. Хотя это правда, что нет find, locateи т. д. в других разделах, так что это не должно быть там, чтобы устранить неоднозначность одно и то же имя, используемое в различных разделах руководство (например, unlink(1)vs unlink(2)), те из нас, кто привык к соглашению, видят это как ссылку на страницу руководства .
Уоррен Янг
35

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

Таким образом, locateэто намного быстрее, чем find, но может быть неточным, если база данных (может рассматриваться как кэш) не обновляется (см. updatedbКоманду).

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

user435943
источник
7

findновичок или случайный пользователь Unix не может успешно использовать без тщательного изучения справочной страницы. Исторически, некоторые версии findдаже не использовали эту -printопцию по умолчанию , добавляя враждебность к пользователю.

locate менее гибок, но намного более интуитивен для использования в общем случае.

Рассел Борогове
источник
1
С другой стороны, программа locate должна поддерживать БД и периодически запускаться, поэтому я отключил ее на всех серверах Linux, которые находятся в нашей частной сети.
Rui F Ribeiro
2
Что в этом сложного? find . -name 'nametosearch'или -inameбез учета регистра. Замените .путь к каталогу для поиска, отличного от текущего каталога. Там это 90% требований начинающего пользователя, даже не затрагивая файловое перетаскивание. (Обычно я использую find . -iname '*partialfilename*'и, если я ищу /, я использую, find / -maxdepth 5 -iname '*partialname*'который сокращает время поиска, находя все, что мне интересно, в 90% случаев. Там, 75% требований промежуточных пользователей.) :)
Wildcard
2

Небольшой недостаток locate заключается в том, что он может не индексировать область интересующей вас файловой системы. В настольных системах Debian, например Linux Mint 17.2, файл /etc/updatedb.conf настроен так, что исключает некоторые области из рассмотрения. , включая / tmp, / var / spool и /home/.ecryptfs.

Игнорирование /home/.ecryptfs предотвращает раскрытие имен файлов в зашифрованных каталогах посторонним пользователям. Однако, если ваш домашний каталог зашифрован с помощью ecryptfs, это также означает, что ваш домашний каталог не проиндексирован, и поэтому locate никогда не найдет ничего в вашем домашнем каталоге. Это может сделать его в значительной степени бесполезным для вас (это делает для меня). В дополнение к отсутствию результатов, процесс updatedb будет периодически загружать ваш диск без какой-либо выгоды, а также может быть отключен, если вы являетесь основным или единственным пользователем системы.

Джим
источник