суббота, 2 декабря 2006 г.

Find, или поиск в Linux.

Сегодня я хочу описать поиск в Linux. Сразу хочу заметить что существует множество разных способов для реализации поиска в Linux. Сейчас, например очень сильно развивается проект beagle. Но я буду говорить о стандартных методах поиска в Linux и Unix. А именно я хочу описать пользование набором программ findutils.

Из набора программ, содержащихся в этом пакете, нас будет интересовать только find и xargs.
Начнем с find. Команда find представляет собой универсальный инструмент для поиска, она позволяет искать файлы и каталоги, просматривать все каталоги в системе или только заданный, искать на файлы заданную глубину и файлы с указанными атрибутами. Обычно пользователи знают что для поиска в Linux существует команда find, но использования этой команды заканчивается на двух трех известных опциях. Для эффективного же поиска, желательно изучить большинство доступных опций.

Использование:



find [-H] [-L] [-P] [путь...] [выражение]

-P - никогда не следовать символьным ссылкам. Эта опция включена по умолчанию;
-L - следовать символьным ссылкам. При этом команда find показывает информацию о файле, на который указывает данная ссылка.
-H - не следовать символьным ссылкам за исключением когда обрабатываются аргументы командной строки. Информация берется из самой ссылки

Путь по умолчанию: текущий каталог; выражение по умолчанию: -print; выражение может состоять из операторов, опций, тестов и действий:

операторы (в порядке уменьшения приоритета; -and берется по умолчанию, если не дано других):
( EXPR ) ! EXPR -not EXPR EXPR1 -a EXPR2 EXPR1 -and EXPR2
EXPR1 -o EXPR2 EXPR1 -or EXPR2 EXPR1 , EXPR2

опции, зависящие от положения (всегда верно): -daystart -follow -regextype

обычные опции:
-depth --help -maxdepth УРОВНИ -mindepth УРОВНИ -mount -noleaf
--version -xdev -ignore_readdir_race -noignore_readdir_race

тесты: (N могут быть +N или -N или N): -amin N -anewer ФАЙЛ -atime N -cmin N
-cnewer ФАЙЛ -ctime N -empty -false -fstype ТИП -gid N -group ИМЯ
-ilname ШАБЛОН -iname ШАБЛОН -inum N -ipath ШАБЛОН -iregex ШАБЛОН
-links N -lname ШАБЛОН -mmin N -mtime N -name ШАБЛОН -newer ФАЙЛ
-nouser -nogroup -path ШАБЛОН -perm [+-]РЕЖИМ -regex ШАБЛОН
-wholename ШАБЛОН -size N[bcwkMG] -true -type [bcdpflsD] -uid N
-used N -user ИМЯ -xtype [bcdpfls]

действия: -delete -print0 -printf ФОРМАТ -fprintf ФАЙЛ ФОРМАТ -print
-fprint0 ФАЙЛ -fprint ФАЙЛ -ls -fls ФАЙЛ -prune -quit
-exec КОМАНДА ; -exec КОМАНДА {} + -ok КОМАНДА ;
-execdir КОМАНДА ; -execdir КОМАНДА {} + -okdir КОМАНДА ;

Опишем наиболее используемые из них:

- name - поиск файлов, имена которых соответствуют заданному шаблону;
- print - поместить запись полных имен найденных файлов в стандартный поток вывода;
- perm - поиск файлов по режиму доступа;
- user - поиск файлов принадлежащих данному пользователю
-nouser - поиск файлов принадлежащих не существующему пользователю, т.е. которого нет в /etc/passwd;
-group - аналогично с -user, только для группы;
-nougroup - аналогично -nouser, только для несуществующей группы;
- mtime -n (+n) - поиск файлов которые модифицировались менее чем -n или более чем +n дней назад;
- atime - поиск по дате -последнего чтения;
- ctime - -последнего изменения атрибутов файла;
- type - поиск указанного типа файлов. Т.е. f - обычный файл, d - каталог и т.д.;
- size n - поиск файлов размером n единиц; единицы: c - байт, k - килобайт, b -блок (в зависимости от системы);
- mount - поиск в текущей файловой системе;
- exec - выполнение команды shell для найденных файлов.

Примеры использования команды find:

$ find /home -user serhiy
Найти все файлы в директории /home и всех поддиректориях принадлежащие пользователю serhiy

$ find ~ -name *.c
В вашей домашней директории найдет все файлы с расширением .с. Например helloworld.c

$ find . -name "[A-Z]*"
В текущем каталоге и его подкаталогах найдет файлы начинающиеся с большой буквы. Заметте что выражение для поиска задано в "..."

$ find /var/www/ -mtime -10
Найти файлы в каталоге /var/www/ и его подкаталогах которые были изменены менее чем 10 дней назад

$ find /var/www/ -mtime +30 -name "*.php"
Найти все .php файлы в каталоге /var/www/ и его подкаталогах которые были изменены более чем 30 дней назад

$ find . -perm 777
Найти все файлы в текущем каталоге, которые имеют права доступа 777.

Я думаю, поняв эти примеры, Вы сможете легко найти нужные вам файлы в Linux. Следующим шагом будет совместное использование find и xargs.

Выше я уже упоминал о опции -exec. С помощью этой опции команда find передает указанному интерпритатору shell все найденный файлы для исполнения, которые обрабатываются один раз. Но могут быть трудности с тем, что длина командной строки может быть ограничена, поэтому если файлов слишком много, система выдаст ошибку. Команда xargs как раз решает эту проблему. Дело в том, что эта команда обрабатывает файлы полученные от find не сразу все, как -exec, а порциями.

Рассмотрим некоторые примеры использования find c xargs:

$ find . -perm 777 | xargs rm
Команда find находит в данном каталоге файлы с атрибутами 777, и команда rm удаляет их.

Или скажем вы хотите найти в домашнем каталоге файл name.c и изменить его права доступа на 777:
$ find ~ -name name.c | xargs chmod 777

Надеюсь данная статья помогла Вам найти то что Вы искали.

9 коммент.:

virens комментирует...

Сергей, изучаю ваш блог и безумно радуюсь постам - нахожу много того, чего давно хотел найти.
Только не постите слишком часто, а то быстро закончатся темы. В остальном - очень надеюсь, что вы не бросите блог. Посещаемость к вам придёт, будьте уверены.

serhiy cherevko комментирует...

>Только не постите слишком часто, а то >быстро закончатся темы

В точку! Спасибо за дельный совет. Лучше написать одну заметку, но лучше. Да и вообще, я хотел бы писать заметки с такой частотой, с которой эти проблемы сами ко мне приходят. А за последнее время тем открыл действительно многовато. Но это только потому, что только начало. Хотел пристреляться в написании.

ceval комментирует...

Хорошая заметка

serhiy cherevko комментирует...

"Хорошая заметка"
Спасибо, будем стараться:).

ruby.freeman комментирует...

спасибище!

Lampdocs комментирует...

Очень даже неплохо. Пожалуй, одно из лучших руководств по find, которые я видел.

Uri комментирует...

Отстой.
Перепечатанный маленький кусочек мана и 4 тривиальнейших примера - это фигня.

p.s. Ничего личного.

Andy комментирует...

Лол... что же в ней хорошего ?)
а за конструкцию "find | xargs" вообще надо руки с корнем вырывать.
Афтар наверное относится к тем кто делает cat | grep вместо grep :)

MisterTito комментирует...

спасибо огромное !!! очень помогли !