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

ДЕЙСТВИЕ ОПИСАНИЕ
-print Выводит полный путь с именем файла в стандартный вывод
-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

Отдельные части синтаксиса команды 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.

Мои эксперименты показали, что KFind не использует find.
Мои эксперименты показали, что KFind не использует find.

Пустим ищейку по следу

ПК против людей

Хотя такие программы, как 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

Личные инструменты
  • Купить электронную версию
  • Подписаться на бумажную версию