найти против найти

30

Есть команды findи locateдля поиска файлов на диске.

Я знаю, что findрекурсивно обрабатывает все необходимые подкаталоги для поиска файлов и поэтому работает медленно, но актуально, в то время как locateиспользует базу данных, которая обновляется время от времени (когда именно?), Чтобы быстро показывать результаты, которые могут быть устаревшими.

Есть ли другие отличия? В каких ситуациях один предпочел бы тот или другой? И когда locateбаза данных обновляется обычно?

Byte Commander
источник
1
manpages.ubuntu.com/manpages/trusty/man8/updatedb.8.html «updatedb обычно запускается ежедневно cron (8) для обновления базы данных по умолчанию».
Rinzwind
@Rinzwind Связанный ответ U & L - это круто, жаль, что мы не можем создавать дубликаты между сайтами. Но знаете ли вы больше о cronjob, когда именно он будет работать? После запуска? Только в определенное время (я думаю, что я прочитал 1-2 утра или что-то в этом роде)? Что произойдет, если он будет закрыт в это время? Он запускается, когда компьютер находится в режиме ожидания? Как я могу узнать возраст базы данных?
Byte Commander
2
@ByteCommander - вот для чего anacron. Я не знаю, установлен ли он по умолчанию на настольных системах / серверах, но на ноутбуках. Он запускается при загрузке и проверяет, должны ли какие-либо задания cron выполняться, пока система выключена, и запускает их. Это действительно полезно, но может вызвать некоторые проблемы, если у вас есть задания, запланированные далеко от полуночи. Это может привести к тому, что задание будет запущено при загрузке, а затем снова, когда придет время - возможно, намного меньше, чем через 24 часа (для ежедневной работы.)
Джо
@Joe Так будет ли он работать во время загрузки и замедлять его, или он будет работать через некоторое время после загрузки, или он обычно работает с таким низким приоритетом, что он просто запускается, когда система почти находится в режиме ожидания?
Byte Commander

Ответы:

27

locateдействительно хорош только для поиска файлов и их отображения людям. Вы можете сделать с ним несколько вещей, но я бы не стал доверять этому достаточно, чтобы разобрать, и, как вы говорите, невозможно гарантировать состояние внутренней базы данных, тем более что она запускается /etc/cron.daily/mlocateтолько один раз в день!

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

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

Оли
источник
2
Я считаю, locateчто гораздо быстрее, если я хочу искать всю мою файловую систему. И вы можете вручную обновить базу данных, используя updatedbперед использованием.
Hytromo
Вы знаете, как точно настроен этот cronjob? Работает ли он в определенное время или когда система находится в режиме ожидания или через n минут после запуска? Потому что я думаю, что где-то читал, что это запланировано на 1-2 часа ночи, когда моя машина обычно выключается. Не обновится ли он тогда, кроме как вручную ( sudo updatedb)? И есть ли шанс увидеть сколько лет базе данных?
Byte Commander
grep run-parts /etc/crontabВы увидите, что они управляются через anacron(что, как вы увидите man anacron, более устойчиво к системам, которые не работают постоянно). Из того, что я вижу, он должен запускаться при загрузке, если вы пропустите исходное время cron.
Оли
2
Я обнаружил, что locate не индексирует мои съемные / размонтированные разделы, поэтому, если я хочу что-то найти на них, я должен использовать find. Конечно, locate не обладает всеми удивительными опциями, которые находит -exec command {} \;команда - например, запускать команду для каждого найденного файла. Мне действительно нравится использовать, locate -bкоторый ограничивает поиск, чтобы найти файлы, которые соответствуют конечному компоненту имени - без остальной части пути. Я часто пробую это сначала, потому что это так быстро. Кроме того, вы можете запустить в sudo updatedbлюбое время, чтобы обновить базу данных locate.
Джо
если вам нужен поиск в реальном времени, который также несколько прост, вы можете использовать что-то вродеls -R | grep 'file_name.txt'
Джена
9

Как бы мне ни нравился Оли (а это очень много!), Я не согласен с ним в findкоманде. Мне это не нравится

find Команда занимает более трех минут

Возьмем для примера эту простую команду:

$ time find / -type f -name "mail-transport-agent.target"
find: ‘/lost+found’: Permission denied
find: ‘/etc/ssmtp’: Permission denied
find: ‘/etc/ssl/private’: Permission denied
    (... SNIP ...)
find: ‘/run/user/997’: Permission denied
find: ‘/run/sudo’: Permission denied
find: ‘/run/systemd/inaccessible’: Permission denied

real    3m40.589s
user    0m4.156s
sys     0m8.874s

Он занимает более трех минут для findпоиска все , начиная с /. По умолчанию появляется множество сообщений об ошибках, и вы должны искать их, чтобы найти то, что вы ищете. Тем не менее, это лучше, чем grepискать строку на всем диске, что занимает 53 часа : `grep` для всех файлов на строку занимает много времени

Я знаю, что могу поиграться с параметрами команды find, чтобы она работала лучше, но суть здесь в том, сколько времени требуется для запуска.

locate команда занимает меньше секунды

Теперь давайте использовать locate:

$ time locate mail-transport-agent.target
/lib/systemd/system/mail-transport-agent.target

real    0m0.816s
user    0m0.792s
sys     0m0.024s

Команда locate занимает меньше секунды!

updatedb по умолчанию запускается только один раз в день

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

$ time sudo updatedb

real    0m3.460s
user    0m0.503s
sys     0m1.167s

Хотя это займет 3 секунды, это мало по сравнению с find3 + минутами команды.

Я обновил мой, sudo crontab -eчтобы включить строку внизу:

# m h  dom mon dow   command
  0 0  1   *   *     /bin/journalctl --vacuum-size=200M
*/5 *  *   *   *     /usr/bin/updatedb

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

Но нет никаких атрибутов?

Вы можете передать locateвывод другим командам. Например, если вам нужны атрибуты файла, вы можете использовать:

$ locate mail-transport-agent.target | xargs stat
  File: '/lib/systemd/system/mail-transport-agent.target'
  Size: 473         Blocks: 8          IO Block: 4096   regular file
Device: 10305h/66309d   Inode: 667460      Links: 1
Access: (0644/-rw-r--r--)  Uid: (    0/    root)   Gid: (    0/    root)
Access: 2018-03-31 18:11:55.091173104 -0600
Modify: 2017-10-27 04:11:45.000000000 -0600
Change: 2017-10-28 07:18:24.860065653 -0600
 Birth: -

Резюме

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

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

WinEunuuchs2Unix
источник
@EliahKagan Но команда find прокручивала и перечисляла все каталоги и файлы на всех дисках и разделах. Казалось, что он работает, и я ожидал распечатку в конце ... В любом случае, речь шла не о «исправлении» поиска команды find, а о получении времени. Запуск locate / display-auto-brightnessзанимает 17 секунд, а также отображает каждый каталог и файл на всех дисках.
WinEunuuchs2Unix
@EliahKagan Я понимаю. --regexбыло необходимо, потому что с моей строкой поиска было возвращено слишком много результатов. Я найду два новых примера для поиска, найду и обновлю свой ответ через несколько минут.
WinEunuuchs2Unix
1
Чтобы прояснить точку зрения Элии, эта findкоманда означает «напечатать имена файлов всех файлов в каталогах /и display-auto-brightness». Я думаю, что вы хотели использовать find / -name display-auto-brightness, но даже это печатает много ненужных ошибок «Отказано в доступе».
wjandrea
@wjandrea Да, как я уже сказал, дело не в том, чтобы найти файл, а во времени команды find. Теперь я перезапускаю тесты с действительными параметрами после очистки кешей. Тогда я обновлю ответ.
WinEunuuchs2Unix
1
@Win Нет, ваш пример все еще действителен, и я не думаю, что время обработки сильно меняется, независимо от того, найден файл или нет.
wjandrea