СправошнаяПоиск

Find и Locate в Linux — как найти файлы на сервере

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