Проверки
Допустим, мы хотим получить список каталогов. Для этого добавим в команду следующую проверку:
[me@linuxbox ~]$ find ~ -type d | wc -l
1695
Добавив проверку -type d, мы ограничились поиском только каталогов. Но точно так же можно ограничить поиск только обычными файлами:
[me@linuxbox ~]$ find ~ -type f | wc -l
38737
В табл. 17.1 перечислены проверки типов файлов, наиболее часто используемых с командой find.
Таблица 17.1. Проверки типов файлов в find
Тип файлов
Описание
b
Специальный файл блочного устройства
c
Специальный файл символьного устройства
d
Каталог
f
Обычный файл
l
Символическая ссылка
Добавив дополнительные проверки, можно выполнять поиск файлов по размеру и имени. Давайте найдем все обычные файлы с именами, соответствующими шаблону *.JPG, и имеющие размер больше 1 мегабайта:
[me@linuxbox ~]$ find ~ -type f -name "*.JPG" -size +1M | wc -l
840
В этом примере мы добавили проверку -name с шаблоном имени файла. Обратите внимание, что шаблон заключен в кавычки, чтобы предотвратить подстановку имен файлов командной оболочкой. Далее мы добавили проверку -size со строкой +1M. Начальный символ «плюс» указывает, что требуется искать файлы, размер которых превышает указанное число. Начальный символ «минус» изменил бы значение строки на противоположное: «меньше указанного числа». Число без знака означает: «в точности соответствует значению». Буква M в конце определяет единицы измерения – мегабайты (Megabytes). В табл. 17.2 перечислены символы, которые можно использовать для обозначения единиц измерения.
Команда find поддерживает множество разнообразных проверок. В табл. 17.3 приводится краткое описание наиболее часто используемых из них. Обратите внимание, что в случаях, когда требуется числовой аргумент, допустимо использование формы записи с символами + и -, обсуждавшейся выше.
Таблица 17.2. Единицы измерения, поддерживаемые командой find
Символ
Единица измерения
b
Блоки размером по 512 байт (используется по умолчанию, если иное не указано явно)
c
Байты
w
2-байтные слова
k
Килобайты (Kilobytes, блоки по 1024 байт)
M
Мегабайты (Megabytes, блоки по 1 048 576 байт)
G
Гигабайты (Gigabytes, блоки по 1 073 741 824 байт)
Таблица 17.3. Проверки, поддерживаемые командой find
Проверка
Описание
-cmin n
Соответствует файлам или каталогам, содержимое или атрибуты которых последний раз изменялись точно n минут назад. Чтобы выразить условие «менее n минут назад», используйте -n; чтобы выразить условие «более n минут назад», используйте +n
-cnewer имя
Соответствует файлам или каталогам, содержимое или атрибуты которых последний раз изменялись позже, чем у файла с указанным именем
-ctime n
Соответствует файлам или каталогам, содержимое или атрибуты (то есть разрешения) которых последний раз изменялись более чем n*24 часа назад
-empty
Соответствует пустым файлам и каталогам
-group группа
Соответствует файлам или каталогам, принадлежащим указанной группе. Группа может задаваться именем или числовым идентификатором группы
-iname шаблон
Действует так же, как проверка -name, но различает регистр символов
-inum n
Соответствует файлам с номером индексного узла (inode) n. Эту проверку удобно использовать для поиска всех жестких ссылок на определенный индексный узел
-mmin n
Соответствует файлам или каталогам, содержимое которых последний раз изменялось n минут назад
-mtime n
Соответствует файлам или каталогам, содержимое которых последний раз изменялось n*24 часов назад
-name шаблон
Соответствует файлам и каталогам, имена которых совпадают с указанным шаблоном
-newer имя
Соответствует файлам и каталогам, содержимое которых последний раз изменялось позже, чем у файла с указанным именем. Эта проверка может пригодиться в сценариях, выполняющих резервное копирование файлов. Каждый раз в процессе создания резервной копии можно обновлять файл (например, файл журнала) и затем с помощью find определять, какие файлы изменились с момента последнего обновления
-nouser
Соответствует файлам и каталогам, не принадлежащим какому-либо допустимому пользователю. Эту проверку можно использовать для поиска файлов, принадлежащих удаленным учетным записям, или для обнаружения следов злоумышленников
-nogroup
Соответствует файлам и каталогам, не принадлежащим какой-либо допустимой группе
-perm режим
Соответствует файлам или каталогам с указанным режимом доступа. Режим может выражаться восьмеричным числом или иметь символическую форму
-samefile имя
Действует так же, как проверка -inum. Соответствует файлам с тем же номером индексного узла (inode), что и файл с указанным именем
-size n
Соответствует файлам с размером n
-type c
Соответствует файлам с типом c
-user имя
Соответствует файлам или каталогам, принадлежащим пользователю с указанным именем. Аргумент имя может быть именем или числовым идентификатором пользователя
Это не полный список. Дополнительные детали ищите на странице справочного руководства (man) для команды find.
Операторы
Несмотря на большое число проверок, поддерживаемых командой find, мы все еще нуждаемся в способе определения логических отношений между проверками. Например, представьте, что в некотором каталоге мы хотим найти все файлы и подкаталоги с небезопасными разрешениями. Для этого можно было бы выполнить поиск всех файлов с разрешениями, отличающимися от 0600, и каталогов с разрешениями, отличающимися от 0700. К счастью, find поддерживает возможность комбинирования проверок с помощью логических операторов, с целью определить более сложные критерии отбора. Выразить вышеупомянутую проверку можно так:
[me@linuxbox ~]$ find ~ ( -type f -not -perm 0600 ) -or ( -type d -not –perm 0700 )
Ф-фу! Как неизящно! Что все это значит? На самом деле операторы перестанут казаться избыточно сложными, как только вы с ними познакомитесь поближе (табл. 17.4).
Имея список операторов под рукой, попробуем разобрать команду find. На самом верхнем уровне мы видим, что проверки объединены в две группы, разделенные оператором -or:
(выражение 1) -or (выражение 2)
Таблица 17.4. Логические операторы, поддерживаемые командой find
Оператор
Описание
-and
Соответствует, если выполняются условия в проверках с обеих сторон от оператора. Можно сократить до -a. Обратите внимание, что в отсутствие операторов по умолчанию подразумевается -and
-or
Соответствует, если выполняется условие с одной из сторон от оператора. Можно сократить до -o
-not
Соответствует, если условие в проверке, следующей за оператором, не выполняется. Можно сократить до -!
( )
Группируют проверки и операторы для формирования крупных выражений. Используются для управления порядком проверок. По умолчанию проверки выполняются слева направо. Часто используются для изменения порядка проверок по умолчанию, чтобы получить желаемый результат. Даже если скобки не нужны, иногда полезно включать их, чтобы сделать команды более наглядными. Не забывайте, что круглые скобки имеют специальное значение для командной оболочки, поэтому их нужно экранировать, чтобы они передавались команде find как аргументы. Обычно экранирование выполняют с помощью символа обратного слеша
В этом есть определенный смысл, потому что мы хотим найти файлы с одним набором разрешений и каталоги – с другим. Но если выполняется поиск и файлов и каталогов, почему используется оператор -or вместо -and? Потому что find, выполняя обход файлов и каталогов, оценивает их по одному, чтобы понять, соответствует ли файл или каталог указанным проверкам. Команде требуется узнать, является ли очередной элемент файлом или каталогом с «плохими» разрешениями. Один и тот же элемент не может соответствовать сразу двум условиям. То есть если развернуть сгруппированные выражения, можно увидеть следующее:
(файл с плохими разрешениями) -or (каталог с плохими разрешениями)
Наша следующая задача — проверить «плохие разрешения». Как это сделать? Фактически никак. Но мы можем проверить «неудовлетворительные разрешения», зная, что такое «удовлетворительные разрешения». В случае с файлами удовлетворительными являются разрешения 0600, для каталогов — 0700. Выражение, проверяющее «неудовлетворительные» разрешения, выглядит так:
-type f -and -not -perms 0600
а для каталогов так:
-type d -and -not -perms 0700
Как отмечалось в табл. 17.4, оператор -and можно просто удалить, так как он подразумевается по умолчанию. Теперь, объединив все вместе, мы получим окончательную команду:
find ~ (-type f -not -perms 0600) -or (-type d -not -perms 0700)
Однако поскольку круглые скобки имеют специальное значение для командной оболочки, их нужно экранировать, чтобы предотвратить интерпретацию скобок командной оболочкой. Для этого достаточно добавить обратный слеш перед каждой из них.
Логические операторы имеют еще одну важную особенность, с которой необходимо разобраться. Представьте, что у нас есть два выражения, разделенных логическим оператором:
выражение1 -оператор выражение2
Выражение1 будет вычислено в любом случае, а вот будет ли вычислено выражение2, зависит от оператора. В табл. 17.5 показано, как это работает.
Таблица 17.5. Действие логических операторов -and/-or команды find
Результат выражения1
Оператор
Выражение2...
Истина
-and
Всегда вычисляется
Ложь
-and
Никогда не вычисляется
Истина
-or
Никогда не вычисляется
Ложь
-or
Всегда вычисляется
Почему так происходит? Это сделано для повышения производительности. Возьмем для примера оператор -and. Мы знаем, что выражение выражение1 -and выражение2 не может быть истинным, если выражение1 вернет ложный результат, поэтому нет смысла вычислять выражение2. Аналогично, если имеется выражение выражение1 -or выражение2 и выражение1 вернет истинный результат, нет смысла вычислять выражение2, так как уже известно, что выражение1 -or выражение2 является истинным.
Это удобно, поскольку такой порядок вычислений помогает повысить скорость выполнения. Но почему это так важно для нас? Потому что мы можем использовать данную особенность для управления выполнением операций, о которых рассказывается далее.