Відповіді:
locate(1)
має лише одну велику перевагу перед find(1)
: швидкістю.
find(1)
, однак, має багато переваг перед locate(1)
:
find(1)
є первинним, повертаючись до першої версії AT&T Unix . Ви навіть знайдете його у вбудованому Linuxs через 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
. (Я ігнорую псевдоніми та незначні відмінності, як -?
vs -h
vs. --help
)
BSD і Mac OS X постачають BSD locate
.
Більшість Linuxes постачають GNU locate
, але Red Hat Linuxes та Arch надсилають mlocate
. 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)
приймають глобальні шаблони так 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)
покладається на оновлювані години або дні в базі даних, її вихід може бути застарілим. (Це проблема застарілого кешу .) Ця монета має дві сторони:
locate
може називати файли, які вже не існують.
GNU locate
і mlocate
мати -e
прапор , щоб зробити це перевірити наявність файлу перед друком з імені кожного файлу , він виявив в минулому, а це роз'їдає деякі locate
переваги в швидкості, і не доступні в BSD , locate
крім.
locate
не вдасться назвати файли, створені з моменту останнього оновлення бази даних.
Ви навчитесь бути недовірливими до locate
результатів, знаючи, що це може бути неправильно.
Існують способи вирішення цієї проблеми, але я не знаю жодної реалізації в широкому застосуванні. Наприклад, є rlocate
, але, схоже, він не працює проти жодного сучасного ядра Linux.
find(1)
ніколи не має більше привілеїв, ніж користувач, яким він керує.
Оскільки locate
забезпечує глобальний сервіс для всіх користувачів системи, він хоче updatedb
запустити свій процес так, root
щоб він міг бачити всю файлову систему. Це призводить до вибору проблем безпеки:
Запустити updatedb
як root, але зробити його вихідний файл всебічно читаним, щоб він locate
міг працювати без спеціальних привілеїв. Це ефективно розкриває імена всіх файлів у системі всім користувачам. Цього може бути недостатньо для порушення безпеки, щоб викликати справжню проблему.
BSD locate
налаштований таким чином на Mac OS X та FreeBSD.
Запишіть базу даних як читабельну лише root
, і зробіть locate
setuid
root, щоб вона могла читати базу даних. Це означає, locate
що потрібно реалізовувати систему дозволів ОС, щоб не відображати файли, які ви не можете бачити. Це також збільшує поверхню атаки вашої системи, особливо ризикуючи атакою кореневої ескалації .
Створіть спеціального " locate
" користувача або групу для володіння файлом бази даних та позначте locate
двійковий код як setuid/setgid
для цього користувача / групи, щоб він міг читати базу даних. Це не перешкоджає атакам ескалації привілеїв само по собі, але значно пом’якшує шкоду, яку можна завдати.
mlocate
налаштовано таким чином на Red Hat Enterprise Linux .
Однак у вас все ще виникає проблема, оскільки якщо ви можете використовувати налагоджувач locate
або змусити його скинути ядро, ви можете потрапити на привілейовані частини бази даних.
Я не бачу способу створити по-справжньому "безпечну" locate
команду, якщо не запускати її окремо для кожного користувача в системі, що позбавляє велику частину її переваги над find(1)
.
Підсумок, обидва дуже корисні. locate(1)
краще, коли ви просто намагаєтесь знайти певний файл за назвою, який ви знаєте, що існує, але ви просто не пам'ятаєте, де саме він знаходиться. find(1)
краще, коли у вас є цілеспрямована область для огляду або коли вам потрібно будь-яке з її багатьох переваг.
find -- "$dir"
не надійна ( $dir
може бути прийнята за присудок), ніякого способу перевірки на ознаки симпосилання, проблеми стану раси ... Для мене find
і locate
вирішення двох різних проблем. Є багато місць, де використання знаходження нереально (наприклад, каталоги, що містять мільйони файлів). locate - система індексації, обмежена іменами файлів.
locate
були приблизно схожими find / -type f | gzip > locate.gz
, іzgrep "$1" <locate.gz
locate
є в findutils
пакеті, а його updatedb
програма реалізована в умовах find(1)
. Так що в цьому сенсі locate(1)
насправді потрібно find(1)
. :)
find
, locate
і т.д. в інших розділах , так що не повинно бути там , щоб неоднозначність таке ж ім'я , що використовується в різних розділах Посібник (наприклад, unlink(1)
проти unlink(2)
), ті, хто звик до конвенції, бачать це як посилання на чоловічу сторінку.
locate
використовує заздалегідь вбудовану базу даних, яку слід регулярно оновлювати, в той час як find
ітерація над файловою системою для пошуку файлів.
Таким чином, locate
це набагато швидше find
, але може бути неточним, якщо база даних - можна розглядати як кеш - не оновлюється (див. updatedb
Команду).
Крім того, find
можна запропонувати більш детальну інформацію, оскільки ви можете фільтрувати файли за кожним її атрибутом, locate
використовуючи при цьому шаблон, відповідний іменам файлів.
find
не може новачок або випадковий користувач Unix успішно користуватися без ретельного ознайомлення зі сторінкою man. Історично склалося, що деякі версії find
навіть не замовчували цю -print
опцію, що сприяло неприязні користувачеві.
locate
менш гнучка, але набагато інтуїтивніша у використанні у загальній справі.
find . -name 'nametosearch'
або -iname
для нечутливих до регістру. Замініть .
шлях до каталогу для пошуку, крім поточного каталогу. Там на 90% вимог початківця користувача покрито, навіть не потрапляючи в глобальний файл. (Я зазвичай використовую, find . -iname '*partialfilename*'
і якщо я шукаю /
, я використовую, find / -maxdepth 5 -iname '*partialname*'
що скорочує час пошуку, шукаючи все, що мене цікавить 90% часу. Там 75% вимог проміжних користувачів.) :)
Невеликим недоліком пошуку є те, що він може не індексувати область файлової системи, яка вас цікавить. У настільних системах Debian, наприклад Linux Mint 17.2, файл /etc/updatedb.conf налаштований так, щоб виключити певні області з розгляду , включаючи / tmp, / var / spool та /home/.ecryptfs.
Ігнорування /home/.ecryptfs не дозволяє іменам файлів у зашифрованих каталогах не піддаватися впливу несанкціонованих користувачів. Однак якщо ваш домашній каталог зашифрований за допомогою encryptfs, це також означає, що ваш домашній каталог не індексується, і, таким чином, пошук не знайде нічого у вашому домашньому каталозі. Це може зробити вас в значній мірі непотрібним (це для мене). Окрім того, що не знайде результатів, оновлений процес періодично завантажує ваш диск без жодної користі, а також може бути відключений, якщо ви головний чи єдиний користувач системи.