- Подписка на печатную версию:
- Подписка на электронную версию:
- Подшивки старых номеров журнала (печатные версии)
LXF99:Файлы
Материал из Linuxformat.
Содержание |
Файлы: ищите и обрящете
Засунули что-то неизвестно куда? Рецепт майонеза? Письма тетушки Гвен? Огромный скачанный файл? Не беда! Д-р Крис Браун все вам найдет.
Один из способов оценки относительной важности задач, ради которых люди используют Linux — определение количества различных приложений, написанных для решения этих задач. Исходя из огромного количества программ «поиска чего-нибудь», можно заключить, что чаще всего люди сразу же что-то теряют! На этом уроке мы проведем обзор ряда приложений, с помощью которых можно искать файлы и прочие данные по их названию, атрибутам или содержимому.
Поиск по имени файла
Самый простой поиск — это поиск по имени файла, и здесь удобно начать с шаблона имени файла в оболочке. Например, команда
$ ls *invoice*
выведет список всех файлов текущего каталога, имена которых содержат строку invoice. Не очень впечатляет? Тогда попробуйте
$ ls */*invoice*
Эта команда выведет список всех файлов со строкой invoice в имени, которые содержатся в текущем каталоге и во всех его подкаталогах. Можно расширить диапазон поиска до любого желаемого уровня, например, так:
$ ls *invoice* */*invoice* */*/*invoice*
Для поиска файла по имени во всей файловой системе подойдет утилита slocate. Например, команда
$ slocate invoice
найдет все файлы, имена которых содержат строку invoice. Так как slocate использует индексированный список имен файлов, то работает она с молниеносной быстротой. Этот индекс формируется программой updatedb (то же самое делает команда slocate с ключом -u), обычно запускаемой раз в день с помощью cron или anacron. В моем дистрибутиве Ubuntu 7.04 база данных slocate находится в файле /var/lib/slocate/slocate.db. Это единственный недостаток slocate — команда не найдет файлы, которые были созданы после последнего запуска updatedb.
В выводе find часто можно видеть вереницы сообщений об ошибках, касающихся каталогов, к которым у вас нет прав доступа. Иногда из-за них невозможно добраться до значимой информации. А подавить их легко: отправьте их в устройство «черной дыры» – /dev/null, приписав к командной строке 2> /dev/null.
S значит «безопасный»
Если вам интересно, то s в названии команды slocate восходит к слову «безопасный» ('secure'). И вот в чем здесь дело: программа updatedb (которая строит индекс) работает с привилегиями администратора, чтобы иметь доступ ко всем файлам. Поэтому в индексе slocate.db могут быть файлы, невидимые обычным пользователям (например, системные файлы или личные файлы других пользователей). Индекс slocate включает информацию о владельце файла и правах доступа, и программа slocate не покажет те файлы, соваться в которые вам не полагается. По-моему, раньше была еще программа locate, не отличавшаяся такой щепетильностью, но в современных дистрибутивах Linux slocate и locate указывают на одну и ту же утилиту.
Спецпоиск: which и whereis
Иногда результат команды which может ввести в заблуждение, если переданная ей команда окажется также и встроенной командой оболочки bash. Например, результат выполнения команды
$ which kill /bin/kill
сообщает, что утилита kill находится в каталоге /bin. Однако kill – это и встроенная команда bash, поэтому если я введу команду типа
$ kill -HUP 1246,
будет выполнена встроенная команда kill, а не внешняя.
Чтобы узнать, является ли команда встроенной, псевдонимом (alias) или внешней, можно использовать команду type, например, так:
$ type kill kill is a shell builtin
Для полноты картины упомянем о более узко направленных утилитах для поиска: whereis и which. Программа whereis производит поиск исполняемого файла, исходного кода и документации (страницы руководства) для заданной команды, просматривая каталоги из заранее определенного списка. Например, команда:
$ whereis ls ls: /bin/ls /usr/share/man/man1/ls.1.gz
выводит информацию о местонахождении исполняемого (двоичного) файла и man-страницы для команды ls. Команда which еще более специализирована. Она просто ищет путь до заданной команды и выводит первый результат. Например, команда
$ which vi /usr/bin/vi
сообщает, что команда vi — это исполняемый файл /usr/bin/vi. По сути, это ответ на вопрос: «Если бы я ввел команду vi, то какая программа запустилась бы на самом деле?»
Накачанный поиск: find
На другом конце шкалы — утилита-чемпион поиска, find. Кроме поиска по имени файла, через find возможен поиск по владельцу, правам доступа, времени последнего доступа, размеру файла и многим другим критериям. Плата за эту гибкость, естественно, сложный синтаксис командной строки. Вот вам пример, чтобы вы ухватили идею, а в детали мы углубимся позже:
$ find /etc -name '*.conf' -user cupsys -print find: /etc/ssl/private: Permission denied find: /etc/cups/ssl: Permission denied /etc/cups/cupsd.conf /etc/cups/printers.conf
В этом примере команда find ищет в каталоге /etc (и во вложенных каталогах) все файлы, имена которых заканчиваются на .conf и владельцем которых является пользователь cupsys.
В общем случае синтаксис команды find таков:
$ find <где искать> <что искать> <что с этим делать>
Часть «где искать» — просто список каталогов для поиска, разделенных пробелами. Для каждого из них find рекурсивно спустится во все вложенные каталоги. В таблице «Критерии поиска find» в конце сттьи перечислены самые полезные критерии поиска — часть «что искать», а во врезке в таблице поменьше, «Действия find», перечислены самые полезные действия (часть «что с этим делать»). Оба эти перечня не полны: для более подробной информации обратитесь к man-странице. Если никакого действия не задано, подразумевается -print, в результате которого путь и имя файла передаются в стандартный поток вывода — так команда find используется чаще всего. Пожалуй, стоит упомянуть, что многие критерии поиска find используются скорее с целью выполнения над найденными файлами каких-либо административных операций (допустим, резервного копирования), чем для того, чтобы помочь найти файлы, которые вы случайно посеяли.
Действия find
ДЕЙСТВИЕ | ОПИСАНИЕ |
---|---|
Выводит полный путь с именем файла в стандартный вывод | |
-ls | Выводит полный листинг файла (эквивалентно команде ls -dils) |
-delete | Удаляет файл |
-exec command | Выполняет указанную команду. Все последующие аргументы до появления; считаются аргументами команды. Строка {} заменяется именем текущего файла. |
Критерии поиска для find
СИНТАКСИС | ОПИСАНИЕ | ПРИМЕР |
---|---|---|
-name string | Имя файла соответствует строке (можно употреблять шаблоны) | -name '*.jpg' |
-iname string | То же самое, что -name, но без учета регистра | -iname '*tax*' |
-user username | Владельцем файла является username | -user chris |
-group groupname | Группой владельца файла является groupname | -group admin |
-type x | Файл типа 'x'. Возможные типы:
f – обыкновенный файл d – каталог l – символическая ссылка c – символьное устройство b – блочное устройство p – именованный канал (FIFO) | -type d |
-size +N | Размер файла больше N блоков по 512 байт (суффикс c — для байт, k — для килобайт, M — для мегабайт) | -size +100M |
-size -N | Размер файла меньше N блоков (суффикс c — для байт, k — для килобайт, M — для мегабайт) | -size -50c |
-mtime -N | Последнее изменение файла было менее чем N дней назад | -mtime -1 |
-mtime +N | Последнее изменение файла было менее чем N дней назад | -mtime -1 |
-mmin -N | Последнее изменение файла было менее чем N минут назад | -mmin -10 |
-perm mode | Точное соответствие прав доступа к файлам. Права доступа могут быть записаны в восьмеричном виде или в символьной нотации, поддерживаемой chmod | -perm 644 |
-perm -mode | Установлены все биты разрешений, указанные в mode | -perm -ugo=x |
-perm /mode | Установлен любой из битов разрешений, указанных в mode | -perm /011 |
Учимся на примерах
Отдельные части синтаксиса команды find называют выражениями (или, более формально, предикатами). Например, -uname cupsys – это предикат. Команда find проверяет каждый файл в заданном каталоге и вычисляет значения всех предикатов для этого файла. Каждый предикат возвращает true или false, и результаты всех предикатов объединяются логическим «И». Если хотя бы один предикат возвращает значение false, значения остальных не вычисляются.
Рассмотрим команду:
$ find . -user chris -name '*.txt' -print
Если предикат -user chris возвращает значение false (т.е. chris не является владельцем файла), то значения остальных предикатов не вычисляются. Только если каждый из предикатов -user chris и -name '*.txt' возвращает true, вычисляется предикат –print (который выводит имя файла в стандартный поток вывода и тоже возвращает true).
Этот подход ликвидирует проблему переполнения списка аргументов, которая повредила нам в предыдущем случае. Помните, что find может искать файлы не только по имени, но и по многим другим параметрам, а grep позволяет использовать регулярные выражения, а не только фиксированный текст, поэтому возможности здесь гораздо шире, чем может показаться из этого простого примера. Если его синтаксис непонятен, прочтите врезку «Правда о find» слева вверху. В этом примере предикат -exec grep -q Hudson {} \; возвращает true, если grep находит вхождение строки Hudson в заданном файле, и false, если нет. Если значение предиката – false, find не вычисляет следующие выражения, т.е. не выполняет действие -print.
Чтобы разобраться во всем синтаксисе команды, потребуется время, поэтому, быть может, пригодятся некоторые примеры…
Пример 1 Это простой поиск по имени файла. Поиск начинается в моем домашнем каталоге, ищутся все файлы PowerPoint (.ppt). Обратите внимание, что мы поместили шаблон имени файла в кавычки, чтобы оболочка не развернула его. Мы хотим передать команде именно аргумент '*.ppt', а о соответствии шаблону пусть заботится find.
$ find ~ -name '*.ppt'
Пример 2 В разделе «что искать» может быть несколько условий, и по умолчанию они объединяются через «логическое И», то есть при поиске отбираются файлы, для которых выполняются все условия. К примеру, поищем подкаталоги в /var, владельцем которых является daemon:
$ find /var -type d -user daemon
Пример 3 Показывает, как объединить условия по «ИЛИ» вместо объединения по «И». В каталоге /etc мы ищем либо файлы, владельцем которых является cupsys, либо пустые файлы:
$ find /etc -user cupsys -or -size 0
Пример 4 Оператор ! используется, чтобы получить отрицание от условия. Найдем файлы в каталоге /bin, владельцем которых не является root:
$ find /usr/bin ! -user root
Пример 5 Условия, содержащие числовые сравнения, часто сбивают с толку. Помните, что «+» перед числом означает «больше чем», «-» — «меньше чем», а если нет ни того, ни другого — find ищет точное соответствие. В трех строках ниже производится три поиска файлов: тех, что были изменены за последние десять минут, более чем год назад и ровно 4 дня назад (третий поиск, наверное, не самый остро необходимый).
$ find ~ -mmin -10 $ find ~ -mtime +365 $ find ~ -mtime 4
Пример 6 Из всех условий, наверное, сложнее всего те, в которых есть проверка по правам доступа к файлу. Вот неплохой пример — он производит поиск файлов с правами доступа 644 (в символьном виде их можно представить как rw-r--r--):
$ find ~ -perm 644
Пример 7 Поищем файлы, изменять которые разрешено каждому (то есть и владельцу, и группе и всем остальным). Приведенные варианты одинаковы; в первом используется традиционная запись в восьмеричной системе, во втором — символьная запись, применяемая командой chmod:
$ find ~ -perm -222 $ find ~ -perm -ugo=w
Пример 8 Теперь ищем файлы, изменять которые можно кому-то конкретно: или владельцу, или группе владельца, или остальному миру
$ find ~ -perm /222 $ find ~ -perm /ugo=w
Пример 9 Пока мы использовали только действие по умолчанию -print, которое выводит список файлов. Вот пример, в котором используется действие -exec, которое перемещает все найденные файлы в каталог для резервного копирования. Здесь есть несколько вещей, которые нужно отметить. Обозначение {} будет заменено на полный путь найденного файла, а ';' используется для обозначения окончания команды, следующей за -exec. Помните, что ';' — это также специальный символ оболочки, и нужно поставить перед ним обратный слэш, чтобы оболочка его не обрабатывала.
$ find ~ -mtime +365 -exec mv {} /tmp/mybackup \;
В Linux доступен поиск через Google Desktop 1.0. Для запуска он требует glibc 2.3.2+ и gtk+ 2.2.0 и выше. В нашем обзоре в LXF97 мы дали ему 6/10, так как сочли, что ему еще есть куда расти. Загрузите его и сделайте выводы сами!
Неважно, как его звать; внутри-то что?
Как мы убедились, средства поиска типа find могут искать файлы по имени, размеру, владельцу, времени доступа и многим другим параметрам, но не могут искать файлы по содержимому. Оказывается, файлы достаточно изящно находятся по содержимому при помощи grep, используемой совместно с шаблонами оболочки для файлов. Вот пример, взятый из моей собственной файловой системы:
$ grep -l Hudson */* Desktop/suse_book_press_release.txt google-earth/README.linux Mail/inbox.ev-summary Mail/sent-mail.ev-summary snmp_training/enterprise_mib_list
Здесь мы просим grep вывести имена файлов, содержащих строку Hudson. Шаблон */* разворачивается оболочкой и означает список всех файлов, находящихся на один уровень ниже текущего каталога. Если нужно наложить некоторые условия на имя файла, это можно сделать примерно так:
$ grep -l Hudson */*.txt Desktop/search_tools.txt Desktop/suse_book_press_release.txt
тогда команда будет искать только файлы с расширением .txt. В принципе, можно расширить диапазон поиска и на большее количество уровней, но на практике весьма вероятна ситуация, когда подставленных файлов будет столько, что строка со списком аргументов превысит допустимую длину. С этим я и столкнулся, попробовав
$ grep -l Hudson */* */*/* bash: /bin/grep: Argument list too long
Более эффективный подход — использовать grep совместно с find. Поиск файлов с расширением .txt, содержащих строку Hudson и находящихся в моем домашнем каталоге ('~'), выглядит так:
$ find ~ -name '*.txt' -exec grep -q Hudson {} \; -print /home/chris/Desktop/search_tools.txt /home/chris/Desktop/suse_book_press_release.txt
Графические средства
До сих пор мы занимались утилитами поиска, работающими в командной строке; но, конечно, имеются и графические средства. В Gnome есть графический инструмент поиска gnome-search-tool, показанный на рис. 1. После запуска программа предоставляет минимально необходимый интерфейс, через который указывается маска для имени файла и каталог для поиска. Постепенно можно добавить новые критерии поиска; некоторые из них показаны на рисунке. Эти критерии понятны из нашего разговора о find, и, честно говоря, для поиска gnome-search-tool в фоновом режиме запускает find. Откуда я это знаю? Ну, мы попробовали переименовать исполняемый файл find и обнаружили, что после этого gnome-search-tool выдал ошибку «Не могу запустить дочерний процесс find».
В KDE есть похожее средство под названием KFind, с немного иначе организованным интерфейсом: критерии поиска разделены на три вкладки, показанные на рис. 2.
Пустим ищейку по следу
Хотя такие программы, как find и Beagle, впечатляют, нам пока еще далеко до машинных средств поиска, имитирующих возможности человека. Например, мы не можем спросить компьютер: «Где та картинка с коровами на пляже?» (если, конечно, не позаботились назвать ее cows_on_beach.jpg). Нельзя также потребовать найти все MP3-файлы с соло на виолончели. Поэтому – эй, молодежь! Где ваши таланты? Пора кодировать!
Названный по имени ищейки, известной острым нюхом и умением выслеживать, Beagle — в другой лиге средств поиска. Цитирую страницу проекта Beagle (http://beagleproject.org): «Beagle — это средство поиска, которое исследует ваше личное информационное пространство и находит все, что бы вы ни искали». Оно может искать в документах самого различного типа: обычном тексте, документах OpenOffice.org и Microsoft Office, файлах PDF и HTML, man-страницах, в других источни ках информации, таких как почтовые папки и адресные книги Evolution и KMail, заметки в Tomboy и KNotes и RSS-листы. (Полный список мож но найти на странице http://beagle-project.org/Supported_Filetypes).
Beagle написан на .NET, и ему необходимы среда выполнения Mono и несколько библиотек. Полтора года назад я писал книгу, и, пытаясь получить для нее рабочую версию Beagle, столкнулся с мириадами зависимостей и проблемой несовместимости версий. Сейчас, похоже, программа созрела — с большинством современных дистрибутивом поставляется Beagle, который работает «из коробки», а иногда Beagle интегрируется в Gnome. Внизу показан снимок Beagle в Ubuntu 7.04. Я поискал по фразе «Linux Format» и нашел немало вхождений в файло вой системе и в почтовом архиве. Для рабочего стола KDE есть графи ческий клиент Kerry Beagle; на экранном снимке в верхней части страницы он показан запущенным в SUSE Linux. Если вам интересно, Kerry Beagle — другая разновидность гончих; то, что ее название начинается с 'K' — сущий подарок для фанатов KDE.
Для быстрого поиска Beagle использует предварительно сформи рованный индекс, но этот индекс гораздо динамичнее того, что раз в день создает программа slocate. При первом запуске, Beagle забирается в ваш домашний каталог и индексирует все данные. Если у вас много файлов, сообщений электронной почты или других документов, или ваш компьютер сильно загружен, для полного индексирования всех данных может потребоваться несколько часов. Beagle также использует inotify — индекс динамически обновляется, если в системе происходят какие-то изменения. Индексирование выполняется демоном beagled, который запускается под обычным пользователем (не под администратором) и имеет доступ только к вашему домашнему каталогу. Beagle — отличное средство поиска информации в вашем личном пространстве, но не в системных файлах. Процесс индексации специально ограничивает использование ресурсов процессора во избежание чрезмерной загрузки компьютера. Однако знайте, что индексы съедают много дискового пространства. FAQ по Beagle предупреждает, что размер индекса составляет 5-10 процентов от размера индексируемых данных, но в моей системе он занял около двух процентов (размер индекса — 71 МБ, а файловой системы — 3,6 ГБ). Индекс в виде иерархического набора файлов хранится в каталоге ~/.beagle.
Хотя Beagle' чаще всего используется через графический интерфейс, в нем есть и инструменты командной строки — в частности, beagle-query, и удобные средства администрирования, включая beagle-config, с помощью которого можно настроить процесс индексирования, и beagle-status, который предоставляет регулярно обновляемую информацию о ходе индексирования демоном beagled. LXF
Другой софт
Searchmonkey — средство для сравнения файлов и их содержимого на Gtk+. http://searchmonkey.sourceforge.net
Strigi — небольшой поисковый демон для извлечения данных из файлов, например, длительности аудиороликов, содержимого документов или разрешения изображений. Не привязан к конкретному рабочему столу (Gnome или KDE). http://strigi.sourceforge.net
Tracker позволяет искать документы так же, как Spotlight в OS X. http://www.gnome.org/projects/tracker