Поиск по сайту:

Как использовать «Найти и найти» для поиска файлов в Linux


Введение

Одна из проблем, с которой сталкиваются пользователи, впервые изучающие работу с Linux, заключается в том, как найти файлы, которые они ищут.

В этом руководстве рассказывается, как использовать команду find с подходящим названием. Это поможет вам искать файлы в вашей системе, используя различные фильтры и параметры. Также будет кратко рассмотрена команда locate, которую можно использовать для поиска файлов другим способом.

Предпосылки

Чтобы следовать этому руководству, вам потребуется доступ к компьютеру с операционной системой на базе Linux. Это может быть либо виртуальный частный сервер, к которому вы подключились с помощью SSH, либо ваша локальная машина. Обратите внимание, что это руководство было проверено с использованием сервера Linux с Ubuntu 20.04, но приведенные примеры должны работать на компьютере с любой версией любого дистрибутива Linux.

Если вы планируете использовать удаленный сервер, чтобы следовать этому руководству, мы рекомендуем вам сначала выполнить наше руководство по начальной настройке сервера. Это создаст для вас безопасную серверную среду, включая пользователя без полномочий root с привилегиями sudo и брандмауэр, настроенный с помощью UFW, которые вы сможете использовать для развития своих навыков работы с Linux.

Примечание. Чтобы проиллюстрировать, как работают команды find и locate, примеры команд в этом руководстве выполняют поиск файлов, хранящихся в разделе /, или команды корневой каталог. Из-за этого, если вы вошли в терминал как пользователь без полномочий root, некоторые из примеров команд могут включать в свой вывод Отказано в доступе.

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

Поиск по имени

Самый очевидный способ поиска файлов — по их имени.

Чтобы найти файл по имени с помощью команды find, вы должны использовать следующий синтаксис:

  1. find -name "query"

Это будет чувствительно к регистру, то есть поиск query отличается от поиска Query.

Чтобы найти файл по имени, но игнорировать регистр запроса, используйте параметр -iname:

  1. find -iname "query"

Если вы хотите найти все файлы, которые не соответствуют определенному шаблону, вы можете инвертировать поиск с помощью -not:

  1. find -not -name "query_to_avoid"

Кроме того, вы можете инвертировать поиск, используя восклицательный знак (!), например:

  1. find \! -name "query_to_avoid"

Обратите внимание: если вы используете !, вы должны экранировать символ обратной косой чертой (\), чтобы оболочка не пыталась интерпретировать его до find может действовать.

Поиск по типу

Вы можете указать тип файлов, которые хотите найти, с помощью параметра -type. Это работает следующим образом:

  1. find -type type_descriptor query

Вот некоторые дескрипторы, которые можно использовать для указания типа файла:

  • f: обычный файл
  • d: каталог
  • l: символическая ссылка
  • c: символьные устройства
  • b: заблокировать устройства

Например, если вы хотите найти все символьные устройства в вашей системе, вы можете ввести следующую команду:

  1. 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:

  1. 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 подразумевается каждый раз, когда вы включаете два выражения. Вы также можете вернуть результаты, удовлетворяющие любому из выражений, разделив их опцией -или:

  1. find -name query_1 -or -name query_2

В этом примере будут найдены все файлы, имена которых соответствуют либо query_1, либо query_2.

Фильтрация по времени и размеру

find предоставляет множество способов фильтрации результатов по размеру и времени.

Размер

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

  • c: байты
  • k: килобайты
  • M: мегабайты
  • G: гигабайты
  • b: блоки по 512 байт

Для иллюстрации следующая команда найдет в каталоге /usr каждый файл размером ровно 50 байт:

  1. find /usr -size 50c

Чтобы найти файлы размером менее 50 байт, вы можете использовать этот синтаксис:

  1. find /usr -size -50c

Чтобы найти в каталоге /usr файлы размером более 700 мегабайт, вы можете использовать эту команду:

  1. find /usr -size +700M

Время

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

  • Время доступа: время последнего чтения или записи файла.
  • Время модификации: время последнего изменения содержимого файла.
  • Время изменения: время последнего изменения метаданных индексного дескриптора файла.

Вы можете основывать свои поиски find на этих параметрах, используя параметры -atime, -mtime и -ctime, соответственно. Для любого из этих параметров вы должны указать значение, указывающее, сколько дней в прошлом вы хотите выполнить поиск. Подобно параметрам размера, описанным ранее, вы можете добавить к этим параметрам символы плюс или минус, чтобы указать «больше» или «меньше».

Например, чтобы найти файлы в каталоге /usr, которые были изменены в течение последнего дня, выполните следующую команду:

  1. find /usr -mtime 1

Если вам нужны файлы, к которым обращались менее дня назад, вы можете запустить эту команду:

  1. find /usr -atime -1

Чтобы найти файлы, метаинформация которых была изменена более 3 дней назад, вы можете выполнить следующее:

  1. find /usr -ctime +3

Эти параметры также имеют сопутствующие параметры, которые можно использовать для указания минут вместо дней:

  1. find /usr -mmin -1

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

find также может выполнять сравнение с эталонным файлом и возвращать более новые:

  1. find / -newer reference_file

Этот синтаксис вернет каждый файл в системе, который был создан или изменен позже, чем эталонный файл.

Поиск по владельцу и разрешениям

Вы также можете искать файлы по пользователю или группе, которой принадлежит файл, используя параметры -user и -group соответственно. Чтобы найти каждый файл в каталоге /var, принадлежащий пользователю syslog, выполните следующую команду:

  1. find /var -user syslog

Точно так же вы можете указать файлы в каталоге /etc, принадлежащие теневой группе, набрав:

  1. find /etc -group shadow

Вы также можете искать файлы с определенными разрешениями.

Если вы хотите сопоставить точный набор разрешений, вы можете использовать этот синтаксис, указав разрешения с помощью восьмеричной записи:

  1. find / -perm 644

Это будет соответствовать файлам с точно указанными разрешениями.

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

  1. find / -perm -644

Это будет соответствовать любым файлам, имеющим дополнительные разрешения. В этом случае будет найден файл с разрешениями 744.

Фильтрация по глубине

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

Если вы следуете примерам из этого руководства, было бы разумно создать эти файлы и каталоги в каталоге /tmp/. /tmp/ — это временный каталог, что означает, что любые файлы и каталоги в нем будут удалены при следующей загрузке сервера. Это будет полезно для целей данного руководства, поскольку вы можете создать столько каталогов, файлов и ссылок, сколько захотите, не беспокоясь о том, что они впоследствии засорят вашу систему.

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

Создайте примерную структуру каталогов в каталоге /tmp/ с помощью следующей команды:

  1. mkdir -p /tmp/test/level1dir{1..10}/level2dir{1..10}/level3dir{1..10}

После этого заполните эти каталоги несколькими примерами файлов с помощью команды touch:

  1. 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/:

  1. cd /tmp/test

Чтобы получить общее представление о том, как find извлекает файлы из этой структуры, начните с обычного поиска по имени, который соответствует любым файлам с именем file1:

  1. 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:

  1. find -name file1 | wc -l
Output
1111

Это, вероятно, слишком много результатов, чтобы быть полезными для вас в большинстве случаев. Чтобы сузить его, вы можете указать максимальную глубину поиска в каталоге поиска верхнего уровня:

  1. find -maxdepth num -name query

Чтобы найти file1 только в каталогах level1 и выше, можно указать максимальную глубину 2 (1 для каталога верхнего уровня и 1 для каталога level1). каталоги):

  1. 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

Это гораздо более управляемый список.

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

  1. find -mindepth num -name query

Вы можете использовать это, чтобы найти только файлы в конце ветвей каталога:

  1. 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).

Вы можете комбинировать параметры минимальной и максимальной глубины, чтобы сосредоточиться на узком диапазоне:

  1. 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, используя параметр -exec, используя следующий синтаксис:

  1. find find_parameters -exec command_and_options {} \;

{} используется в качестве заполнителя для файлов, которым соответствует find. \; позволяет find узнать, где заканчивается команда.

Например, если вы все еще находитесь в каталоге test/, который вы создали в каталоге /tmp/ на предыдущем шаге, вы можете найти файлы в предыдущем разделе, которые имели разрешения 644 и измените их, чтобы они имели разрешения 664:

  1. find . -type f -perm 644 -exec chmod 664 {} \;

Вы также можете изменить права доступа к каталогу аналогичным образом:

  1. find . -type d -perm 755 -exec chmod 700 {} \;

В этом примере выполняется поиск каждого каталога с разрешениями, установленными на 755, а затем изменяются разрешения на 700.

Поиск файлов с помощью locate

Альтернативой использованию find является команда locate. Эта команда часто работает быстрее и может легко выполнять поиск по всей файловой системе.

Вы можете установить команду в Debian или Ubuntu с помощью apt, обновив списки пакетов и затем установив пакет mlocate:

  1. sudo apt update
  2. sudo apt install mlocate

В Rocky Linux, CentOS и других дистрибутивах, производных от RedHat, вы можете вместо этого использовать команду dnf для установки mlocate:

  1. sudo dnf install mlocate

Причина, по которой locate работает быстрее, чем find, заключается в том, что он опирается на базу данных, в которой перечислены все файлы в файловой системе. Эта база данных обычно обновляется один раз в день с помощью сценария cron, но вы можете обновить ее вручную с помощью команды updatedb. Запустите эту команду сейчас с привилегиями sudo:

  1. sudo updatedb

Помните, что база данных locate всегда должна быть актуальной, если вы хотите найти новые файлы. Если вы добавите новые файлы до выполнения сценария cron или до запуска команды updatedb, они не будут отображаться в результатах вашего запроса.

locate позволяет фильтровать результаты несколькими способами. Самый простой способ использовать его для поиска файлов — использовать следующий синтаксис:

  1. locate query

Это будет соответствовать любым файлам и каталогам, которые содержат строку query в любом месте их пути к файлу. Чтобы возвращать только файлы, имена которых содержат сам запрос, а не каждый файл, содержащий запрос в каталогах, ведущих к нему, вы можете включить флаг -b для поиска только файлов, чье базовое имя ” соответствует запросу:

  1. locate -b query

Чтобы locate возвращал только результаты, которые все еще существуют в файловой системе (имеются в виду файлы, которые не были удалены между последним вызовом updatedb и текущим вызовом locate ), используйте флаг -e:

  1. locate -e query

Вы можете получить статистику по информации, которая каталогизирована locate, используя параметр -S:

  1. 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.