<< Предыдущий раздел | /\ Содержание | >> Следующий раздел

Команды для поиска файлов

Для поиска файлов в Unix предназначены две команды -- find и locate. Первая выполняет поиск непосредственно в момент запуска, а вторая делает поиск по списку файлов (базе данных), который обновляется обычно раз в сутки (в большинстве систем -- поздно ночью или рано утром).

У обеих команд есть как достоинства, так и недостатки. Так, find выдает результаты по текущему, "мгновенному" состоянию диска, но, к примеру, поиск по всему диску может занимать очень много времени. Напротив, locate выполняет поиск очень быстро, но во-первых, в базе данных может быть несколько устаревшая информация, а во-вторых, база данных составляется "из-под" пользователя "nobody" и не содержит информации о тех директориях, которые для него закрыты.

Кроме того, для быстрого поиска файлов, относящихся к программам, в RedHat Linux можно использовать команду rpm с ключом "-qal" в паре с командой grep.

Как find, так и locate позволяют указывать шаблон имени файла, содержащий специальные символы "*", "?" и т.д. Такие шаблоны надо заключать в кавычки, чтобы shell не пытался их интерпретировать.

Поиск по диску сейчас -- find

Вызов find


Команда find ищет в указанных директориях и ниже файлы, отвечающие заданному критерию ("test"). Причем критерием может быть не только имя файла, но и, к примеру, время модификации, размер или тип (файл/директория/линк и т.д). Критерии могут объединяться при помощи булевских операторов, так что можно найти, например, все файлы с расширением .txt размером не более 10К, модифицированные не позднее прошлого месяца.

Формат вызова find следующий:

find [список директорий] [критерий]

Если не указывать директории, то будут найдены все отвечающие указанному критерию файлы в текущей директории и ниже. Если не указывать критерий, то будет выдан список всех файлов из указанных директорий. Если же не указывать ни то, ни другое, то будет выдан список всех файлов из текущей директории.

Директории в списке указываются через пробел. Имена критериев всегда начинаются с "-", аналогично ключам.

Поиск файла по имени


Самое частое использование find -- поиск файлов по имени. Для этого служит критерий "-name", которому указывается шаблон имени. К примеру, чтобы найти на всем диске все файлы с расширением .txt, надо воспользоваться командой

find / -name '*.txt'

GNU-версия find, используемая в Linux, понимает также критерий "-iname", отличающийся тем, что маленькие и большие буквы не различаются. Так, команда

find / -iname '*.exe'
найдет все файлы с расширениями .exe, .EXE, .Exe и т.д.

Поиск с несколькими критериями


Если указать несколько критериев, то find найдет только файлы, соответствующие всем критериям сразу.

К примеру, критерий "-type" позволяет указать тип файла -- обычный ("f"), директория ("d") и т.д. Таким образом, чтобы найти в директории /etc все директории, имена которых начинаются на "cron", надо сделать слежующее:

bobby:~% find /etc -name 'cron*' -type d
find: /etc/X11/xdm/authdir: Permission denied
/etc/cron.daily
/etc/cron.hourly
/etc/cron.monthly
/etc/cron.weekly
bobby:~% _

В то время как поиск просто по имени дал бы несколько лишних файлов:

bobby:~% find /etc -name 'cron*'
find: /etc/X11/xdm/authdir: Permission denied
/etc/rc.d/init.d/crond
/etc/logrotate.d/cron
/etc/cron.daily
/etc/cron.hourly
/etc/cron.monthly
/etc/cron.weekly
bobby:~% _

Исполнение команды с найденными файлами


Кроме критериев команде find можно указывать также действия ("actions"). Если никакое действие не указано, то find по умолчанию добавляет "-print", чтобы напечатать имя файла. Т.е. команда

find / -name '*.txt'
реально работает как

find / -name '*.txt' -print

Наиболее часто требуется действие "-exec", позволяющее выполнить с найденным файлом некую команду, чаще всего -- ls -l.

Пример (выдать "длинный" листинг всех файлов из директории /etc, в имени которых содержится "pass"):

bobby:~% find /etc -name '*pass*' -type f -exec ls -l '{}' ';' 
-rw-r--r--   1 root     root         1362 Apr 16 20:21 /etc/passwd
-rwxr-xr-x   1 root     root           97 Oct 13  1998 /etc/X11/wmconfig/u
serpasswd
find: /etc/X11/xdm/authdir: Permission denied
-rw-r--r--   1 root     root          239 Apr 27  1998 /etc/pam.d/passwd
-rw-r--r--   1 root     root         1362 Apr 16 20:10 /etc/passwd-
-rw-r--r--   1 root     root         1363 Apr 16 20:20 /etc/passwd.OLD
bobby:~% _

Необходимое пояснение: "-exec" воспринимает все, что стоит после него и до слова ";", как команду, которую надо выполнить. Причем сочетание символов "{}" заменяется на имя файла. Поскольку и ";", и "{}" являются специальными символами для shell, их надо "закавычить".

Поиск по списку файлов диска -- locate

Команда locate ищет указанные имена в базе данных, содержащей список файлов. Формат вызова locate следующий:

locate ИМЯ [ИМЯ...]

Пример:

bobby:~% locate Monitors
/usr/X11R6/lib/X11/doc/Monitors
/usr/X11R6/share/Xconfigurator/MonitorsDB
bobby:~% _

При указании нескольких имен locate найдет файлы, соответствующие любому из имен:

bobby:~% locate xsnow xroach
/etc/X11/wmconfig/xsnow
/usr/share/icons/mini/mini-xsnow.xpm
/usr/X11R6/bin/xsnow
/usr/X11R6/include/X11/bitmaps/xsnow
/usr/X11R6/man/man1/xsnow.1x
/usr/X11R6/bin/xroach
/usr/X11R6/man/man1/xroach.man
/var/catman/X11R6/cat1/xroach.man.gz
bobby:~% _

Если ИМЯ не содержит специальных символов шаблона, то locate находит все файлы, в любом месте полного имени которых (т.е. включая директорию) встречается указанная строка. Т.е. locate в этом случае работает просто как grep по списку файлов.

Если же ИМЯ содержит символы "*", "?" или "[]", то locate находит только строки, которые точно соответствуют шаблону.

Например, команда

locate '/usr/X11R6/*jewel'
покажет все файлы из директории /usr/X11R6, имя которых заканчивается на "jewel", а именно программу xjewel, но не man-страницу по ней:

bobby:~% locate '/usr/X11R6/*jewel'
/usr/X11R6/bin/xjewel
bobby:~% _

Для того же, чтобы увидеть все файлы из /usr/X11R6, в имени которых встречается "jewel", надо в конце шаблона также поставить "*":

bobby:~% locate '/usr/X11R6/*jewel*'
/usr/X11R6/bin/xjewel
/usr/X11R6/man/man1/xjewel.1x
bobby:~% _

В любом случае символы "." и "/" не являются особенными. Таким образом, шаблон "*et*pass*" найдет файл /etc/passwd.

Предупреждение
По умолчанию в базу данных, которую просматривает locate, попадают лишь файлы с корневой файловой системы (т.е. /). Если же, к примеру, все home-директории пользователей расположены на отдельном разделе (который монтируется, например, в /home), то администратор системы должен добавить этот раздел в список индексируемых.

В Linux индексирование (т.е. создание базы данных) выполняется программой updatedb, которая автоматически запускается ежедневно при помощи Cron. В RedHat Linux это выполняется из файла /etc/cron.daily/updatedb.cron. Таким образом, чтобы заставить updatedb индексировать, к примеру, раздел, смонтированный в /home, надо просто добавить его (через пробел) в список разделов в ключе "--localpaths" (т.е. чтобы было что-то типа "--localpaths='/ /home").

Замечание
Команда locate есть только в BSD-системах и в Linux, в системах клона SystemV она отсутствует.


<< Предыдущий раздел | /\ Содержание | >> Следующий раздел