Швидкий пошук файлу на ім’я - утиліта locate, Для системного адміністратора

Швидкий пошук файлу на ім'я – утиліта locate

find вирішує практично всі завдання, які можуть виникнути у користувача у зв'язку з пошуком і подальшою обробкою потрібних файлів або каталогів. Однак, досить часто, виникають ситуації, коли вам з одного боку не потрібна вся міцьfind, а з іншого хотілося щоб пошук відбувався швидше, і без значного завантаження системи. Адже запустившиfind з якою-небудь хитрою умовою, що ще викликає зовнішні команди, та вказавши почати пошук з кореневої директорії, можна домогтися того, що система буде настільки завантажена, що ваш системний адміністратор грішною справою подумає про візит кул хацкеров, але ми звичайно не звірі і нашого адміністратора лякати не будемо. Тому для глобального пошуку скористаємося утилітою locate.

Використання locate

Ця утиліта просто незамінна у випадку якщо вам хоча б приблизно відомо ім'я файлу, який потрібно визначити. Відмінна особливість даної команди, скажімо від того ж find, в тому що при роботі вона не сканує по справжньому файлову систему, пошук йде в попередньо побудованій базі, в якій зберігається зліпок з файлової системи. Такий зліпок виконується за допомогою команди locate -u або updatedb, яка по-справжньому перелопачує ваші жорсткі чи мережеві диски, а імена всіх знайдених файлів записує до бази. Природно, що дана процедура досить ресурсомістка, і може займати досить тривалий час. Її запуск зазвичай доручають crontab, який запускає updatedb з необхідною частотою. Частота оновлення бази залежить від того, наскільки часто оновлюється вміст файлової системи, а також наскільки важливою є актуальність даних. Так зазвичай оновлення бази виконуєтьсяавтоматично раз на тиждень, або вручну, після того, як ви або системний адміністратор встановили нову партію свіжого ПЗ. Зазначу, щоб оновити базу, потрібно мати права суперкористувача.

Наведу найпростіший приклад використання:

$ locate traceroute /usr/man/man8/traceroute.8.gz /usr/sbin/traceroute6 /usr/sbin/traceroute $ locate mpg123 /usr/doc/ mpg123-0.59r /usr/doc/mpg123-0.59r/BUGS /usr/doc/mpg123-0.59r/CHANGES /usr/doc/mpg123-0.59r/COPYING / usr/doc/mpg123-0.59r/INSTALL /usr/doc/mpg123-0.59r/JUKEBOX /usr/doc/mpg123-0.59r/README /usr/doc/mpg123-0.59r /TODO /usr/doc/mpg123-0.59r/mp3license /usr/man/man1/mpg123.1.gz /usr/bin/mpg123 $

З наведених прикладів видно три суттєві моменти, що стосуються поведінки locate. По-перше шукаються всі файли та каталоги в іменах яких зустрічається підрядок заданий як аргумент. По-друге, файли виводяться включаючи повний шлях до них. По-третє, заданий підрядок взагалі може не входити в ім'я самого файлу, а зустрічатися в його шляху. Так, у другому прикладі до списку знайдених файлів було повністю включено вміст каталогуmpg123-0.59r.

Іноді потрібно більш точний пошук, коли потрібно обмежити те місце, куди може входити заданий підрядок. Скажімо, якщо нам потрібно знайти тільки файли та каталоги в назву яких входитьmpg123. У цьому випадку можна використовувати шаблони „аля bash“ (пам'ятайте *, ?, [. ]) або більш просунутий варіант, який використовує регулярні вирази. Я віддаю перевагу останній, як потужніший і просунутіший.

Для того щоб повідомити locate, що ви хочете використовувати регулярні вирази, потрібно вказати форму locate -r. Так у нашому випадку запит буде виглядати так:

$ locate -r "mpg123[^/]*$" /usr/doc/mpg123-0.59r /usr/man/man1/mpg123.1.gz /usr/bin/mpg123 $

Рядокmpg123[^/]*$ – просить locate знайти ті файли у яких після підрядки mpg123 може бути нуль чи більше символів, крім символу/, після чого йде кінець рядка. Таким чином, з результату пошуку виключаються рядки виду /usr/doc/mpg123-0.59r/BUGS.

Ще одна корисна можливість це форма виклику locate -i. Параметр -i говорить про те, що потрібно зробити нечутливий до регістру пошук:

$ locate "/etc/dir" /usr/local/share/emacs/21.1/etc/dired-ref.ps /usr/local/share/emacs/21.1/etc/dired-ref.tex $ locate -i "/etc/dir" /usr/local/share/emacs/21.1/etc/dired-ref.ps /usr/local/share/emacs/21.1/etc/ dired-ref.tex /etc/DIR_COLORS $

Використання спільно з іншими командами

Сам собоюlocate не виконує нічого крім виведення імен потрібних файлів. Однак ви не завжди можете задовольнитись лише спогляданням імен та місцезнаходження знайдених файлів. Тут вам на допомогу приходять улюблені трубопроводи, конвеєри та інші радощі командного рядка.

Наприклад, хочемо одержати крім самих файлів ще й інформацію про атрибути цих файлів. У цьому випадку нам на допомогу приходить підстановка команд:

$ locate crontab /usr/man/man1/crontab.1.gz /usr/man/man5/anacrontab.5.gz /usr/man/man5/crontab.5.gz >/usr/bin/crontab /etc/anacrontab /etc/crontab $ls -ld `!!` ls -ld `locate crontab` -rw-r- -r-- 1 root root 370 Mar 3 2000 /etc/anacrontab -rw-r--r-- 1 root root 255 Aug 27 1999 /etc/crontab -rwsr-xr-x 1 root root 21816 Feb 3 2000 /usr/bin/crontab -rw-r--r-- 1 root root 1584 Feb 3 2000 /usr/man/man1/crontab.1.gz -rw-r-- r-- 1 root root 669 Mar 3 2000 /usr/man/man5/anacrontab.5.gz -rw-r--r-- 1 root root 3495 Feb 3 2000 /usr/man/man5/crontab.5.gz $

У цьому прикладі першою командою ми отримали список файлів, що цікавлять нас, а другою передали цей список команді ls -ld, в результаті чого отримали чудовий список з необхідною інформацією. Параметр -d повідомляє ls що замість вмісту каталогів виводити їх атрибути.

Спосіб з підстановкою підходить в тому випадку, якщо у нас не багато файлів. В іншому випадку ми можемо зіткнутися з обмеженням на довжину рядка параметрів ls -l, що передаються. Наприклад:

Як бачимо, варіант не пройшов. Тому якщо очікується велика кількість файлів на виході, краще буде скористатися утилітою xargs яка просто читає свій вхідний потік, розбиває його на рядки, а потім ці рядки невеликими порціями згодовує програмі переданої їй як параметр. Щоб було більш зрозуміло наведу простий приклад у якому видно що робить xargs:

$ ls /usr/ X11R6 etc info man bin games kerberos sbin cvsroot i386-redhat-linux lib share dict i486-linux-libc5 libexec src doc include local tmp

$ ls /usr/ xargs -n 5 echo X11R6 bin cvsroot dict doc etc ігри i386-redhat-linux i486-linux-libc5 include info kerberos lib libexec local man sbin share $

Тут результат виконанняls /usr/ спрямовується на вхідxargs -n 5, який розбиває отримані рядки по п'ять штук і передає їх як аргумент командіecho, як Неважко здогадатися кількість параметрів задається за допомогою параметра-n.

У нашому випадку вказувати кількість параметрів не потрібно, так як воно в даному випадку несуттєве, головне щоб обмеження на розмір аргументу не було перевищено, а це завданняxargs вирішує без сторонньоїдопомоги:

$ locate / xargs ls -ld wc -l 70968 $

Як бачимо такий варіант, на відміну від попереднього, спрацював.

Коли locate не котить.

Як завжди, негативні сторони locate випливають прямо з його позитивних сторін. Так, інформація про файли в базі може застаріти з моменту останнього оновлення, і не відповідати поточному стану файлової системи, деякі файли можуть бути видалені, деякі перейменовані, інші додані. І якщо з видаленням проблем взагалі не виникає, тому що locate після пошуку у своїй базі перевіряє наявність знайдених файлів у системі, то з новими або перейменованими файлами locate не дружить, вони результати будуть відсутні:

Якщо ви і користувач або root в одній особі, то проблема вирішується оновленням бази руками, інакше доведеться користуватися чимось потужнішим, типу find.

Ще один момент, на який варто звернути увагу, це те, що locate зберігає ім'я самого файлу і шлях до нього як рядок, у зв'язку з чим у загальному випадку дізнатися чи є знайдений рядок файлом, символічним посиланням, або каталогом безпосередньо за допомогою locate не можна.

Іноді використання locate неефективне, так наведено трохи штучний приклад, коли ми знаходили всі файли в системі, а потім виводили їх атрибути за допомогоюls -ld. В даному випадку більш правильне рішення є використовувати той же find, справа в тому що в наведеному вище випадку сканування системи відбувається все одно, тільки робить це неlocate, аls, додайте сюди накладні витрати на трубопровід, xargs, в результаті отримуємо:

$ cat /tmp/l locate -f proc / xargs -n 1000 ls -ld $ cat /tmp/f find / -ls 2>/dev/null $ time /tmp /f >/dev/null 3.83user 2.80system0:06.99elapsed 94%CPU (0avgtext+0avgdata 0maxresident)k 0inputs+0outputs (358major+147minor)pagefaults 0swaps $ time /tmp/l &/dv/null

5.41user :11.62elapsed 97%CPU (0avgtext+0avgdata 0maxresident)k 0inputs+0outputs (28176major+11719minor)pagefaults 0swaps

Як видно в даному випадку locate з компанією сів у калюжу, виконуючи поставлене завдання вдвічі повільніше ніж find. Звичайно приклад надуманий, але ілюструє той факт, що перед вирішенням будь-якого завдання не заважає розкинути мізками!