Найти в Дзене
DIGANN.RU | Linux & IT

Linux. Поиск файлов и директорий утилитой find.

Оглавление

Часто пользуюсь поиском файлов и каталогов. Пользуюсь в основном поисков в программе Midnight Commander, но иногда нужно найти что-то на удаленном компьютере, на котором MC не установлен, и как раз для таких случаев есть утили find.

find - утилита поиска файлов по имени и другим свойствам, используемая в UNIX‐подобных операционных системах. Может производить поиск в одном или нескольких каталогах с использованием критериев, заданных пользователем. По умолчанию find возвращает все файлы в рабочем каталоге. Более того, find позволяет применять пользователю определённые действия ко всем найденным файлам. Также поддерживаются регулярные выражения. Для поиска файлов по содержимому следует пользоваться утилитой grep.

Синтаксис команды.

Полный синтаксис команды find:

find [-H] [-L] [-P] [-D debugopts] [-Olevel] [starting-point...] [expression]

Options или параметры [-H] [-L] [-P] [-D debugopts] [-Olevel].

Точка входа [starting-point...] или место с которого будет осуществляться поиск.

Выражение [expression] - часть командной строки после списка "точек- входа". Это своего рода спецификация запроса, описывающая, как мы сопоставляем файлы и что мы делаем с файлами, которые были сопоставлены. Выражение состоит из последовательности элементов:

Проверки или тесты (tests) возвращают значение true или false, обычно на основе какого-либо свойства рассматриваемого файла. Например, проверка -empty имеет значение true только в том случае, если текущий файл пуст.

Действия (actions) - имеют побочные эффекты (например, печать чего-либо в стандартном выводе) и возвращают значение true или false, обычно в зависимости от того, завершились они успешно или нет. Например, действие -print выводит имя текущего файла в стандартном выводе.

Глобальные параметры (global options) влияют на выполнение проверок и действий, указанных в любой части командной строки. Глобальные параметры всегда возвращают значение true. Параметр -depth позволяет выполнять поиск по файловой системе в порядке возрастания глубины.

Позиционные параметры (Positional options) влияют только на проверки или действия, которые следуют за ними. Позиционные параметры всегда возвращают значение true. Например, параметр -regextype является позиционным и определяет диалект регулярных выражений для регулярных выражений, появляющихся позже в командной строке.

Операторы (Operators) объединяют другие элементы в выражении. К ним относятся, например, -o (что означает логическое OR) и -a (что означает логическое AND). Если оператор отсутствует, используется -a.

Действие -print выполняется для всех файлов, для которых все выражение истинно, если только оно не содержит действия, отличного от -prune или -quit. Действия, которые блокируют область печати по умолчанию -delete, -exec, -execdir, -ok, -okdir, -false, -fprint, -fprintf, -ls, -print и -printf.

ВЫРАЖЕНИЕ (EXPRESSION):

Приведу только некоторые из документации.

Проверки или тесты (tests):

Некоторые проверки(тесты), например -newerXY и -samefile, позволяют сравнивать проверяемый в данный момент файл с каким-либо эталонным файлом, указанным в командной строке. Когда используются эти тесты, интерпретация файла ссылок определяется параметрами -H, -L и -P и любыми предыдущими -follow, но файл ссылок проверяется только один раз, во время анализа командной строки. Если файл ссылки не может быть проверен (например, системный вызов stat(2) для него завершается ошибкой), выдается сообщение об ошибке, и find завершает работу с ненулевым статусом.

Числовой аргумент n может быть указан для проверок (например, -amin, -mtime, -gid, -inum, -links, -size, -uid и -used) как +n - больше, чем n, или -n - меньше, чем n, или n - ровно n.

-amin n - последний раз к файлу обращались меньше, больше или ровно n минут назад.

-cmin n - статус файла в последний раз менялся меньше, больше или ровно n минут назад.

-anewer reference - время последнего обращения к текущему файлу является более поздним, чем время последнего изменения данных в ссылочном файле. Если ссылка является символьной и используется параметр -H или -L, то всегда используется время последнего изменения данных файла, на который она указывает.

-name pattern - основа имени файла (путь с удаленными ведущими каталогами) совпадает с шаблоном shell pattern. Поскольку ведущие каталоги удалены, имена файлов, которые рассматриваются на предмет совпадения с -name, никогда не будут содержать косую черту, поэтому `-name a/b' никогда ни чему не будет соответствовать (вероятно, вам нужно использовать -path вместо этого). При попытке сделать это выдается предупреждение, если только не задана переменная окружения POSIXLY_CORRECT. Метасимволы (`*', `?' и `[]') соответствуют '.' в начале базового имени (это изменение в findutils-4.2.2; смотрите в документации в раздел STANDARDS CONFORMANCE). Чтобы игнорировать каталог и файлы, находящиеся в нем, используйте -prune вместо проверки каждого файла в дереве; смотрите пример в описании этого действия. Фигурные скобки не распознаются как особые, несмотря на то, что некоторые оболочки, включая Bash, придают фигурным скобкам особое значение в шаблонах оболочек. Сопоставление имен файлов выполняется с помощью библиотечной функции fnmatch(3). Не забудьте заключить шаблон в кавычки, чтобы защитить его от расширения оболочкой.

Действия (actions):

-delete - удалить файлы или каталоги; значение true, если удаление завершилось успешно. Если удаление завершилось неудачно, выдается сообщение об ошибке, и статус завершения find будет отличным от нуля (когда он в конечном итоге завершится).

Предупреждение: не забывайте, что find вычисляет командную строку как выражение, поэтому, если сначала поставить -delete, find попытается удалить все, что находится ниже указанных вами точек-входа.

-exec command - выполнить команду; значение true, если возвращен статус 0. Все следующие аргументы для find принимаются в качестве аргументов команды, пока не будет найден аргумент, состоящий из ';' . Строка '{}' заменяется текущим именем файла, которое обрабатывается везде, где встречается в аргументах команды, а не только в аргументах, где присутствует отдельно, как в некоторых версиях find. Обе эти конструкции, возможно, потребуется экранировать (с помощью '\') или заключить в кавычки, чтобы защитить их от расширения оболочкой. Примеры использования параметра -exec приведены в разделе ПРИМЕРОВ. Указанная команда выполняется один раз для каждого сопоставленного файла. Команда выполняется в начальной директории. Использование действия -exec неизбежно связано с проблемами безопасности; вместо этого следует использовать параметр -execdir.

Операторы (Operators):

Перечислены в порядке убывания приоритета:

( expr ) - принудительный приоритет. Поскольку круглые скобки используются специально для командной строки, обычно их нужно заключать в кавычки. Во многих примерах для этой цели используется обратная косая черта: '\(...\)' вместо '(...)'.

-not expr - то же, что и !expr, но не совместимо с POSIX.

expr1 expr2 - два выражения подряд объединяются подразумеваемым значением -a; expr2 не вычисляется, если значение expr1 равно false.

expr1 -a expr2 - аналогично expr1 expr2.

expr1 -and expr2 - аналогично expr1 expr2, но не совместимо с POSIX.

expr1 -o expr2 - OR; значение expr2 не вычисляется, если значение expr1 равно true.

expr1 -or expr2 - то же, что и expr1 -o expr2, но не совместимо с POSIX.

expr1 , expr2 - список; всегда вычисляются как expr1, так и expr2. Значение expr1 отбрасывается; значением списка является значение expr2. Оператор запятой может быть полезен для поиска нескольких различных типов объектов, но при этом иерархия файловой системы может быть пройдена только один раз. Действие -fprintf можно использовать для перечисления различных совпадающих элементов в нескольких разных выходных файлах.

ПРИМЕРЫ

Примечание: знак $ в примерах это стандартное приглашение командной оболочки, при копировании команды, этот символ копировать не нужно.

  • Простой подход `find|xargs`

Найдите файлы с именем core в каталоге /tmp и удалите их.

$ find /tmp -name core -type f -print | xargs /bin/rm -f

  • Безопасный подход `find -print0 | xargs -0`

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

$ find /tmp -name core -type f -print0 | xargs -0 /bin/rm -f

Проверка -name выполняется перед проверкой -type, чтобы избежать необходимости вызывать stat(2) для каждого файла.

  • Обработка произвольных точек-входа

Учитывая, что другая программа proggy выполняет предварительную фильтрацию и создает огромный список файлов, разделенных нулями, обработайте их как точки-входа и найдите среди них все обычные пустые файлы:

$ proggy | find -files0-from - -maxdepth 0 -type f -empty

Использование `-files0-from -` означает чтение имен точек-входа из стандартного ввода, т.е. из канала; и -maxdepth 0 гарантирует, что только эти записи будут проверены явно, без обращения к каталогам (в случае, если одна из точек-входа равна единице).

  • Выполнение команды для каждого файла

Запустит file для каждого файла в текущем каталоге.

$ find . -type f -exec file '{}' \;

Обратите внимание, что фигурные скобки заключены в одинарные кавычки '{}', чтобы защитить их от интерпретации как знаков препинания в shell-скрипте. Точка с запятой также экранирована обратной косой чертой \; , хотя в этом случае также можно было бы использовать одинарные кавычки.

Во многих случаях можно предпочесть синтаксис `-exec ... +` или, что еще лучше, `-execdir ... +` из соображений производительности и безопасности.

  • Обход файловой системы только один раз - для выполнения 2 различных действий

Обход файловой системы только один раз, перечисление файлов и каталогов с установленными идентификаторами пользователя в /root/suid.txt и больших файлов в /root/big.txt.

$ find / \
\( -perm -4000 -fprintf /root/suid.txt '%#m %u %p\n' \) , \
\( -size +100M -fprintf /root/big.txt '%-10s %p\n' \)

В этом примере используется символ продолжения строки '\' в первых двух строках, чтобы указать командной строке продолжить чтение команды в следующей строке.

  • Поиск файлов, которые были изменены

Найдите в вашем домашнем каталоге файлы, которые были изменены за последние двадцать четыре часа.

$ find $HOME -mtime 0

Эта команда работает таким образом, потому что время, прошедшее с момента последнего изменения каждого файла, делится на 24 часа, а оставшееся время отбрасывается. Это означает, что для соответствия -mtime 0, файл должен был быть изменен менее чем 24 часа назад.

  • Поиск файлов по разрешениям (permissions)

Найдите файлы, которые являются исполняемыми, но не читаемыми.

$ find /sbin /usr/sbin -executable \! -readable -print

Найдите файлы, которые имеют разрешение на чтение и запись для их владельца и группы, которые другие пользователи могут читать, но не могут записывать.

$ find . -perm 664

Файлы, которые соответствуют этим критериям, но имеют другие установленные биты разрешений (например, если кто-то может запустить файл), не будут сопоставлены.

Выполняйте поиск файлов, которые имеют разрешение на чтение и запись для их владельца и группы и которые могут читать другие пользователи, независимо от наличия каких-либо дополнительных разрешений (например, исполняемого файла).

$ find . -perm -664

Это будет соответствовать файлу, который, например, имеет режим 0777.

Ищите файлы, которые доступны для записи кому-либо (их владельцу, их группе или кому-либо еще).

$ find . -perm /222

Найдите файлы, доступные для записи их владельцем или группой пользователей.

$ find . -perm /220
$ find . -perm /u+w,g+w
$ find . -perm /u=w,g=w

Все три эти команды выполняют одно и то же, но первая использует восьмеричное представление файлового режима, а две другие - символьную форму. Для сопоставления файлов необязательно, чтобы они были доступны для записи как владельцем, так и группой; подойдет любая из них.

Ищите файлы, доступные для записи как их владельцем, так и их группой.

$ find . -perm -220
$ find . -perm -g+w,u+w

Обе эти команды делают одно и то же.

Более подробный поиск по разрешениям.

$ find . -perm -444 -perm /222 \! -perm /111
$ find . -perm -a+r -perm /a+w \! -perm /a+x

Обе эти команды ищут файлы, которые доступны для чтения всем (-perm -444 или -perm -a+r), имеют по крайней мере один установленный бит записи (-perm /222 или -perm /a+w), но не являются исполняемыми ни для кого (! -perm /111 или ! -perm /a+x соответственно).

Надеюсь эта статья окажется вам полезной. Больше информации о том как можно использовать утилиту find смотрите в документации.

Не забываем ставить лайк, подписываться. Пока. ))