Одна из проблем, с которой сталкиваются пользователи, впервые изучающие работу с Linux, заключается в том, как найти файлы, которые они ищут.
В этом руководстве рассказывается, как использовать правильно названную find
команду. Это поможет вам искать файлы в вашей системе, используя различные фильтры и параметры. Также будет кратко рассмотрена locate
команда, которую можно использовать для поиска файлов другим способом.
Предпосылки
Чтобы следовать этому руководству, вам потребуется доступ к компьютеру с операционной системой на базе Linux. Это может быть либо виртуальный частный сервер, к которому вы подключились с помощью SSH, либо ваша локальная машина. Обратите внимание, что это руководство было проверено с использованием сервера Linux с Ubuntu 20.04, но приведенные примеры должны работать на компьютере с любой версией любого дистрибутива Linux.
Если вы планируете использовать удаленный сервер, чтобы следовать этому руководству, мы рекомендуем вам сначала выполнить начальную настройку сервера . Это создаст безопасную серверную среду, включая пользователя без полномочий root с sudo
привилегиями и брандмауэр, настроенный с помощью UFW, который вы сможете использовать для развития своих навыков работы с Linux.
Кроме того, вы можете использовать интерактивный терминал, встроенный в эту страницу, чтобы поэкспериментировать с примерами команд из этого руководства. Щелкните следующее Запустить интерактивный терминал! кнопку, чтобы открыть окно терминала и начать работу в среде Linux (Ubuntu).
Примечание . Чтобы проиллюстрировать, как работают команды find
и locate
, примеры команд в этом руководстве выполняют поиск файлов /
, хранящихся в каталоге или в корневом каталоге . Из-за этого, если вы вошли в терминал как пользователь без полномочий root , некоторые из примеров команд могут включать Permission denied
в свой вывод.
Этого и следовало ожидать, поскольку вы ищете файлы в каталогах, к которым обычные пользователи обычно не имеют доступа. Тем не менее, эти примеры команд должны по-прежнему работать и быть полезными для понимания того, как работают эти программы.
Поиск по имени
Самый очевидный способ поиска файлов — по их имени.
Чтобы найти файл по имени с помощью find
команды, вы должны использовать следующий синтаксис:
find -name "query"
Это будет чувствительно к регистру, то есть поиск query
отличается от поиска Query
.
Чтобы найти файл по имени, но игнорировать регистр запроса, используйте -iname
параметр:
find -iname "query"
Если вы хотите найти все файлы, которые не соответствуют определенному шаблону, вы можете инвертировать поиск с помощью -not
:
find -not -name "query_to_avoid"
Кроме того, вы можете инвертировать поиск, используя восклицательный знак ( !
), например:
find \! -name "query_to_avoid"
Обратите внимание, что если вы используете !
, вы должны экранировать символ обратной косой чертой ( \
), чтобы оболочка не пыталась интерпретировать его до того, как find
сможет действовать.
Поиск по типу
Вы можете указать тип файлов, которые хотите найти, с помощью -type
параметра. Это работает следующим образом:
find -type type_descriptor query
Вот некоторые дескрипторы, которые можно использовать для указания типа файла:
f
: обычный файлd
: каталогl
: символическая ссылкаc
: символьные устройстваb
: блокировать устройства
Например, если вы хотите найти все символьные устройства в вашей системе, вы можете ввести следующую команду:
find /dev -type c
Эта команда специально ищет устройства только в /dev
каталоге, в котором файлы устройств обычно монтируются в системах Linux:
Output
/dev/vcsa5 /dev/vcsu5 /dev/vcs5 /dev/vcsa4 /dev/vcsu4 /dev/vcs4 /dev/vcsa3 /dev/vcsu3 /dev/vcs3 /dev/vcsa2 /dev/vcsu2 /dev/vcs2 . . .
Вы можете искать все файлы, которые заканчиваются .conf
на команду, подобную следующей. В этом примере выполняется поиск соответствующих файлов в /usr
каталоге:
find /usr -type f -name "*.conf"
Output
/usr/src/linux-headers-5.4.0-88-generic/include/config/auto.conf /usr/src/linux-headers-5.4.0-88-generic/include/config/tristate.conf /usr/src/linux-headers-5.4.0-90-generic/include/config/auto.conf /usr/src/linux-headers-5.4.0-90-generic/include/config/tristate.conf /usr/share/adduser/adduser.conf /usr/share/ufw/ufw.conf /usr/share/popularity-contest/default.conf /usr/share/byobu/keybindings/tmux-screen-keys.conf /usr/share/libc-bin/nsswitch.conf /usr/share/rsyslog/50-default.conf . . .
Примечание . В предыдущем примере объединены два find
выражения запроса; а именно -type f
и -name "*.conf"
. Чтобы любой файл был возвращен, он должен удовлетворять обоим этим выражениям.
Вы можете комбинировать такие выражения, разделяя их -and
опцией, но, как показывает этот пример -and
, подразумевается каждый раз, когда вы включаете два выражения. Вы также можете вернуть результаты, которые удовлетворяют любому выражению, разделив их -or
опцией:
find -name query_1 -or -name query_2
В этом примере будут найдены все файлы, имена которых соответствуют либо , query_1
либо query_2
.
Фильтрация по времени и размеру
find
дает вам различные способы фильтрации результатов по размеру и времени.
Размер
Вы можете фильтровать файлы по их размеру с помощью -size
параметра. Чтобы сделать это, вы должны добавить специальный суффикс в конце числового значения размера, чтобы указать, рассчитываете ли вы размер в байтах, мегабайтах, гигабайтах или другом размере. Вот некоторые часто используемые суффиксы размера:
c
: байтk
: килобайтыM
: мегабайтыG
: гигабайтыb
: блоки по 512 байт
Чтобы проиллюстрировать это, следующая команда найдет в /usr
каталоге каждый файл размером ровно 50 байт:
find /usr -size 50c
Чтобы найти файлы размером менее 50 байт, вы можете использовать этот синтаксис:
find /usr -size -50c
Чтобы найти файлы в /usr
каталоге размером более 700 мегабайт, вы можете использовать эту команду:
find /usr -size +700M
Время
Для каждого файла в системе Linux хранит временные данные о времени доступа, времени модификации и времени изменения.
-
Время доступа : время последнего чтения или записи файла.
-
Время модификации : время последнего изменения содержимого файла.
-
Время изменения : время последнего изменения метаданных индексного дескриптора файла.
Вы можете основывать свои find
поиски на этих параметрах, используя параметры -atime
, -mtime
и -ctime
соответственно. Для любого из этих параметров необходимо передать значение, указывающее, сколько дней в прошлом вы хотите выполнить поиск. Подобно параметрам размера, описанным ранее, вы можете добавить к этим параметрам символы «плюс» или «минус», чтобы указать «больше» или «меньше».
Например, чтобы найти файлы в /usr
каталоге, которые были изменены за последний день, выполните следующую команду:
find /usr -mtime 1
Если вам нужны файлы, к которым обращались менее дня назад, вы можете запустить эту команду:
find /usr -atime -1
Чтобы найти файлы, метаинформация которых была изменена более 3 дней назад, вы можете выполнить следующее:
find /usr -ctime +3
Эти параметры также имеют сопутствующие параметры, которые можно использовать для указания минут вместо дней:
find /usr -mmin -1
Это даст файлы, которые были изменены в последнюю минуту.
find
также может выполнять сравнения с эталонным файлом и возвращать более новые:
find / -newer reference_file
Этот синтаксис вернет каждый файл в системе, который был создан или изменен позже, чем эталонный файл.
Поиск по владельцу и разрешениям
Вы также можете искать файлы по пользователю или группе, которой принадлежит файл, используя параметры -user
и -group
соответственно. Чтобы найти каждый файл в /var
каталоге, принадлежащем пользователю syslog , выполните следующую команду:
find /var -user syslog
Точно так же вы можете указать файлы в /etc
каталоге, принадлежащем теневой группе, набрав:
find /etc -group shadow
Вы также можете искать файлы с определенными разрешениями.
Если вы хотите сопоставить точный набор разрешений, вы можете использовать этот синтаксис, указав разрешения с помощью восьмеричной записи:
find / -perm 644
Это будет соответствовать файлам с точно указанными разрешениями.
Если вы хотите указать что-либо, по крайней мере , с этими разрешениями, вы можете поставить перед обозначением разрешений знак минус:
find / -perm -644
Это будет соответствовать любым файлам, имеющим дополнительные разрешения. 744
В этом случае будет сопоставлен файл с разрешениями .
Фильтрация по глубине
В этом разделе вы создадите примерную структуру каталогов, которую затем будете использовать для изучения фильтрации файлов по их глубине внутри структуры.
Если вы следуете примерам в этом руководстве, было бы разумно создать эти файлы и каталоги в /tmp/
каталоге. /tmp/
является временным каталогом , что означает, что любые файлы и каталоги в нем будут удалены при следующей загрузке сервера. Это будет полезно для целей данного руководства, поскольку вы можете создать столько каталогов, файлов и ссылок, сколько захотите, не беспокоясь о том, что они впоследствии засорят вашу систему.
После выполнения команд в этом разделе ваш /tmp/
каталог будет содержать три уровня каталогов, с десятью каталогами на первом уровне. Каждый каталог (включая временный каталог) будет содержать десять файлов и десять подкаталогов.
Создайте примерную структуру каталогов в /tmp/
каталоге с помощью следующей команды:
mkdir -p /tmp/test/level1dir{1..10}/level2dir{1..10}/level3dir{1..10}
После этого заполните эти каталоги несколькими образцами файлов с помощью touch
команды:
touch /tmp/test/{file{1..10},level1dir{1..10}/{file{1..10},level2dir{1..10}/{file{1..10},level3dir{1..10}/file{1..10}}}}
Имея эти файлы и каталоги, перейдите в test/
только что созданный каталог:
cd /tmp/test
Чтобы получить базовое представление о том, как find
будут извлекаться файлы из этой структуры, начните с обычного поиска по имени, который соответствует любым файлам с именами file1
:
find -name file1
Output
./level1dir7/level2dir8/level3dir9/file1 ./level1dir7/level2dir8/level3dir3/file1 ./level1dir7/level2dir8/level3dir4/file1 ./level1dir7/level2dir8/level3dir1/file1 ./level1dir7/level2dir8/level3dir8/file1 ./level1dir7/level2dir8/level3dir7/file1 ./level1dir7/level2dir8/level3dir2/file1 ./level1dir7/level2dir8/level3dir6/file1 ./level1dir7/level2dir8/level3dir5/file1 ./level1dir7/level2dir8/file1 . . .
Это вернет много результатов. Если вы направите вывод в счетчик, вы обнаружите, что есть 1111
общие результаты:
find -name file1 | wc -l
Output
1111
Это, вероятно, слишком много результатов, чтобы быть полезными для вас в большинстве случаев. Чтобы сузить его, вы можете указать максимальную глубину поиска в каталоге поиска верхнего уровня:
find -maxdepth num -name query
Чтобы найти file1
только в level1
каталогах и выше, вы можете указать максимальную глубину 2 (1 для каталога верхнего уровня и 1 для level1
каталогов):
find -maxdepth 2 -name file1
Output
./level1dir7/file1 ./level1dir1/file1 ./level1dir3/file1 ./level1dir8/file1 ./level1dir6/file1 ./file1 ./level1dir2/file1 ./level1dir9/file1 ./level1dir4/file1 ./level1dir5/file1 ./level1dir10/file1
Это гораздо более управляемый список.
Вы также можете указать минимальный каталог, если знаете, что все файлы существуют после определенной точки в текущем каталоге:
find -mindepth num -name query
Вы можете использовать это, чтобы найти только файлы в конце ветвей каталога:
find -mindepth 4 -name file1
Output
./level1dir7/level2dir8/level3dir9/file1 ./level1dir7/level2dir8/level3dir3/file1 ./level1dir7/level2dir8/level3dir4/file1 ./level1dir7/level2dir8/level3dir1/file1 ./level1dir7/level2dir8/level3dir8/file1 ./level1dir7/level2dir8/level3dir7/file1 ./level1dir7/level2dir8/level3dir2/file1 . . .
Опять же, из-за разветвленной структуры каталогов это вернет большое количество результатов (1000).
Вы можете комбинировать параметры минимальной и максимальной глубины, чтобы сосредоточиться на узком диапазоне:
find -mindepth 2 -maxdepth 3 -name file1
Output
./level1dir7/level2dir8/file1 ./level1dir7/level2dir5/file1 ./level1dir7/level2dir7/file1 ./level1dir7/level2dir2/file1 ./level1dir7/level2dir10/file1 ./level1dir7/level2dir6/file1 ./level1dir7/level2dir3/file1 ./level1dir7/level2dir4/file1 ./level1dir7/file1 . . .
>
Такое сочетание этих параметров значительно сужает результаты, возвращая только 110 строк вместо предыдущих 1000.
Выполнение команд по find
результатам
Вы можете выполнить произвольную вспомогательную команду для всего, что find
соответствует, используя -exec
параметр, используя следующий синтаксис:
find find_parameters -exec command_and_options {} \;
Используется {}
в качестве заполнителя для файлов, которые find
соответствуют. \;
Позволяет find
узнать, где заканчивается команда .
Например, предполагая, что вы все еще находитесь в test/
каталоге, который вы создали в /tmp/
каталоге на предыдущем шаге, вы можете найти файлы в предыдущем разделе, у которых есть 644
разрешения, и изменить их, чтобы они имели 664
разрешения:
find . -type f -perm 644 -exec chmod 664 {} \;
Вы также можете изменить права доступа к каталогу аналогичным образом:
find . -type d -perm 755 -exec chmod 700 {} \;
В этом примере выполняется поиск каждого каталога с установленными разрешениями, 755
а затем изменяются разрешения на 700
.
Поиск файлов с помощьюlocate
Альтернативой использованию find
является команда locate
. Эта команда часто работает быстрее и может легко выполнять поиск по всей файловой системе.
Вы можете установить команду в Debian или Ubuntu apt
, обновив списки пакетов и затем установив пакет mlocate
:
sudo apt update
sudo apt install mlocate
В Rocky Linux, CentOS и других дистрибутивах, производных от RedHat, вместо этого вы можете использовать dnf
команду для установки mlocate
:
sudo dnf install mlocate
Причина того, что locate
быстрее, чем find
есть: она опирается на базу данных, в которой перечислены все файлы в файловой системе. Эта база данных обычно обновляется один раз в день с помощью cron-скрипта, но вы можете обновить ее вручную с помощью updatedb
команды. Запустите эту команду сейчас с sudo
привилегиями:
sudo updatedb
Помните, что locate
база данных всегда должна быть актуальной, если вы хотите найти новые файлы. Если вы добавите новые файлы до выполнения сценария cron или до запуска updatedb
команды, они не будут отображаться в результатах вашего запроса.
locate
позволяет фильтровать результаты несколькими способами. Самый простой способ использовать его для поиска файлов — использовать следующий синтаксис:
locate query
Это будет соответствовать любым файлам и каталогам, которые содержат строку query
в любом месте их пути к файлу. Чтобы возвращать только файлы, имена которых содержат сам запрос, вместо каждого файла, содержащего запрос в каталогах, ведущих к нему, вы можете включить -b
флаг для поиска только тех файлов, чье «базовое имя» соответствует запросу:
locate -b query
Чтобы locate
возвращались только те результаты, которые все еще существуют в файловой системе (имеются в виду файлы, которые не были удалены между последним updatedb
вызовом и текущим locate
вызовом), используйте -e
флаг:
locate -e query
Вы можете получить статистику о locate
каталогизированной информации, используя -S
опцию:
locate -S
Output
Database /var/lib/mlocate/mlocate.db: 21015 directories 136787 files 7727763 bytes in file names 3264413 bytes used to store database
Это может быть полезно для получения общего представления о том, сколько файлов и каталогов существует в вашей системе.
Вывод
Обе команды find
и locate
являются полезными инструментами для поиска файлов в вашей системе. Обе являются мощными командами, которые можно усилить, комбинируя их с другими утилитами через конвейеры, но вам решать, какой инструмент подходит для вашей конкретной ситуации.
Отсюда мы рекомендуем вам продолжать экспериментировать с find
и locate
. Вы можете прочитать их соответствующие man
страницы, чтобы узнать о других параметрах, не описанных в этом руководстве, и вы можете анализировать результаты поиска и управлять ими, перенаправляя их в другие команды, такие как wc
, sort
и grep
.