Команда find в Linux: опции -name, -type, -size, -mtime и -delete

Тестовая средаСемейство RHELAlmaLinux 9.8findutils 4.8Учётная запись rootDebian 12 · findutils 4.9 обычная учётная записьПроверено 2026-10-31

Команда find в Linux спускается по порядку от начальной папки и находит файлы и папки, подходящие под условия: имя, тип, размер, время изменения и права. Когда мы создали десять файлов в тестовой папке на сервере AlmaLinux 9 и запускали команду, меняя по одному условию, найденные файлы стали передавать через -exec другим командам, а при удалении сначала проверять список с теми же условиями и только потом применять -delete.

Пути тестовой папки и время файлов в блоках результатов заменены примерными значениями. В выводе сервера Debian 12 примерное значение только у пути домашней папки, остальное приведено без изменений.

1️⃣ Как использовать команду find в Linux

  • ↪️ Начальный путь, -name и -iname

Базовая форма: [find начальный-путь условия]. Без начального пути поиск идёт в текущей папке (.), а без условий выводятся все файлы и папки под начальным путём.

Тест проводился в /root/work с тремя папками и десятью файлами, как показано ниже.

/root/work
docs/
readme.txt450 байт · 3 дня назад
guide.txt5,000 байт
old.tmp64 байта · 10 дней назад
logs/
app.log2MB
cache.tmp512 байт · 10 дней назад
backup/Пустая папка
report.txt1,200 байт
README.md300 байт · 3 дня назад
run.sh18 байт · права 755
my notes.txt150 байт · 3 дня назад · права 600
empty.txt0 байт
find /root/work
/root/work
/root/work/docs
/root/work/docs/readme.txt
/root/work/docs/guide.txt
/root/work/docs/old.tmp
/root/work/logs
/root/work/logs/app.log
/root/work/logs/cache.tmp
/root/work/backup
/root/work/report.txt
/root/work/README.md
/root/work/run.sh
/root/work/my notes.txt
/root/work/empty.txt

find не сортирует результаты по имени; в этом запуске, дойдя до папки docs, он сначала вывел все файлы внутри, а затем перешёл к logs.

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

-name сравнивает с шаблоном только имя файла, а не путь. Заключайте шаблон в одинарные кавычки, чтобы оболочка не раскрыла * первой и передала его в find как есть.

find /root/work -name '*.txt'
/root/work/docs/readme.txt
/root/work/docs/guide.txt
/root/work/report.txt
/root/work/my notes.txt
/root/work/empty.txt

-name учитывает регистр. Поиск имён, начинающихся с readme, нашёл только docs/readme.txt, а с -iname нашёлся и README.md.

find /root/work -name 'readme*'
/root/work/docs/readme.txt
find /root/work -iname 'readme*'
/root/work/docs/readme.txt
/root/work/README.md

find входит в пакет findutils. Версия в первой строке [find --version]: findutils 4.8 на сервере AlmaLinux 9.8 и 4.9 на сервере Debian 12.

2️⃣ find -type d и -maxdepth

  • ↪️ Выбор файлов или папок и глубина поиска

-type f оставляет только обычные файлы, а -type d только папки.

find /root/work -type d
/root/work
/root/work/docs
/root/work/logs
/root/work/backup

Начальный путь /root/work тоже папка, поэтому он появился в первой строке. С -type f на том же пути появились все десять файлов.

-maxdepth задаёт, на сколько уровней спускаться от начального пути. С -maxdepth 1 файлы в docs и logs выпали, и остались только пять файлов прямо под /root/work.

find /root/work -maxdepth 1 -type f
/root/work/report.txt
/root/work/README.md
/root/work/run.sh
/root/work/my notes.txt
/root/work/empty.txt

Наоборот, -mindepth 2 пропустил всё прямо под начальным путём и вывел только пять файлов во вложенных папках.

find /root/work -mindepth 2 -type f
/root/work/docs/readme.txt
/root/work/docs/guide.txt
/root/work/docs/old.tmp
/root/work/logs/app.log
/root/work/logs/cache.tmp

Страница man советует писать глобальные опции вроде -maxdepth сразу после начального пути. -maxdepth 1 после -type f дал те же пять файлов, но в терминале появляется строка предупреждения с просьбой ставить глобальные опции вперёд (по странице man).

Чтобы узнать только количество папок или файлов, передайте вывод в wc -l. Подсчёт вывода -type d дал 4 с учётом начального пути.

find /root/work -type d | wc -l
4

С -maxdepth 1 тоже получилось 4, потому что все три вложенные папки лежат прямо под начальным путём.

find /root/work -maxdepth 1 -type d | wc -l
4

Подсчёт только файлов во вложенных папках через -mindepth 2 дал 5.

find /root/work -mindepth 2 -type f | wc -l
5

3️⃣ Условия размера и времени команды find

  • ↪️ -size, -mtime, -mmin, -newer, -empty

+ перед числом означает больше этого значения, - меньше, а без знака ровно это значение. Единицы -size указаны в таблице ниже (по странице man).

ЕдиницаРазмерДа
c1 байт-size +500c
k1,024 байта-size +1k
M1,048,576 байт-size +1M
G1,073,741,824 байта-size +1G
(нет)Блоки по 512 байт-size +2
find /root/work -type f -size +1k
/root/work/docs/guide.txt
/root/work/logs/app.log
/root/work/report.txt

Больше 1k оказались guide.txt на 5,000 байт, app.log на 2MB и report.txt на 1,200 байт.

find /root/work -size +1M
/root/work/logs/app.log

Когда -size записали дважды как диапазон, остались только два файла больше 1k и меньше 100k.

find /root/work -type f -size +1k -size -100k
/root/work/docs/guide.txt
/root/work/report.txt

-size делит размер на единицу и округляет вверх перед сравнением. Поэтому README.md на 300 байт тоже считается за 1k, и при -size -1k появился только empty.txt размером 0.

find /root/work -type f -size -1k
/root/work/empty.txt

Чтобы проверить условия времени, мы задали время изменения README.md, my notes.txt и docs/readme.txt на 3 дня назад, а двух файлов .tmp на 10 дней назад. У каждого файла есть три времени: доступа, изменения и смены статуса, их можно посмотреть через команду stat.

-mtime считает время с последнего изменения в единицах по 24 часа. При -mtime -1 появились пять файлов, созданных за 24 часа.

find /root/work -type f -mtime -1
/root/work/docs/guide.txt
/root/work/logs/app.log
/root/work/report.txt
/root/work/run.sh
/root/work/empty.txt

При -mtime +7 появились только два файла .tmp с датой 10 дней назад. Эта форма нужна, чтобы проверить список перед удалением старых журналов или временных файлов.

find /root/work -type f -mtime +7
/root/work/docs/old.tmp
/root/work/logs/cache.tmp

-mmin считает так же, но в минутах. Результат -mmin -60 совпал с -mtime -1: те же пять файлов.

find /root/work -type f -mmin -60
/root/work/docs/guide.txt
/root/work/logs/app.log
/root/work/report.txt
/root/work/run.sh
/root/work/empty.txt

-newer находит файлы, изменённые позже опорного файла. С README.md, заданным на 3 дня назад, в роли опорного появились пять файлов, созданных после него.

find /root/work -type f -newer /root/work/README.md
/root/work/docs/guide.txt
/root/work/logs/app.log
/root/work/report.txt
/root/work/run.sh
/root/work/empty.txt

-empty находит и файлы размером 0, и пустые папки: появились пустая папка backup и empty.txt.

find /root/work -empty
/root/work/backup
/root/work/empty.txt

4️⃣ Условия -perm и -user команды find

  • ↪️ Поиск по правам и владельцу, группировка условий

Если после -perm написать только число, ищутся файлы с правами ровно этого значения. -perm 644 исключил run.sh с 755 и my notes.txt с 600, и нашлось восемь файлов.

find /root/work -type f -perm 644
/root/work/docs/readme.txt
/root/work/docs/guide.txt
/root/work/docs/old.tmp
/root/work/logs/app.log
/root/work/logs/cache.tmp
/root/work/report.txt
/root/work/README.md
/root/work/empty.txt

С - перед режимом ищутся файлы, у которых есть все указанные права. Право на выполнение для владельца (u+x) было только у run.sh.

find /root/work -type f -perm -u+x
/root/work/run.sh

С / перед режимом достаточно любого из указанных прав. 6000 это сумма SUID (4000) и SGID (2000), и такая форма нужна для проверки на сервере файлов, которые при запуске работают с правами владельца или группы.

В тестовой папке таких файлов не было, поэтому мы дали run.sh SUID и запустили поиск: появился run.sh.

chmod u+s /root/work/run.sh
find /root/work -type f -perm /6000
/root/work/run.sh

В старых материалах на этом месте стоит -perm +6000. Запуск в таком виде закончился ошибкой [invalid mode].

find /root/work -type f -perm +6000
find: invalid mode '+6000'

Форма + удалена в findutils 4.5.12 (по странице man), поэтому пишите /. Выданный для теста SUID убран через chmod u-s.

-user фильтрует по имени владельца. Все тестовые файлы принадлежат root, поэтому один -user root ничего не отсеивает; после добавления -name для выбора файлов .log остался только app.log.

find /root/work -type f -user root -name '*.log'
/root/work/logs/app.log

-nouser находит файлы, для UID владельца которых нет учётной записи. Это нужно для проверки файлов, оставшихся на сервере после удаления учётной записи; после смены владельца guide.txt на несуществующий UID 1500 появился guide.txt.

chown 1500:1500 /root/work/docs/guide.txt
find /root/work -nouser
/root/work/docs/guide.txt

-nogroup делает ту же проверку для группы, и появился guide.txt, у которого группа тоже изменена на 1500. После теста мы вернули всё через chown root:root.

С -o между условиями достаточно одного из них. При использовании с другим условием вроде -type f заключайте условия, связанные через -o, в скобки. Перед скобками ставьте обратную косую черту, чтобы оболочка не разобрала их первой, а между скобками и условиями оставляйте пробелы.

find /root/work -type f \( -name '*.log' -o -name '*.tmp' \)
/root/work/docs/old.tmp
/root/work/logs/app.log
/root/work/logs/cache.tmp

! обращает условие сразу после него. Поиск файлов, не являющихся .txt, нашёл пять.

find /root/work -type f ! -name '*.txt'
/root/work/docs/old.tmp
/root/work/logs/app.log
/root/work/logs/cache.tmp
/root/work/README.md
/root/work/run.sh

5️⃣ Использование find -exec

  • ↪️ Разница {} \; и {} +, массовая смена прав и связка с grep

-exec запускает команду, указанную после него, для каждого найденного файла, а вместо {} подставляется найденный путь. ; в конце команды пишется как \;, чтобы оболочка не прочитала его первой как разделитель команд.

find /root/work -name '*.log' -exec ls -l {} \;
-rw-r--r-- 1 root root 2097152 Oct  5 14:10 /root/work/logs/app.log

Если закончить через + вместо \;, найденные пути собираются вместе, и команда запускается только один раз. При сравнении через echo \; вывел пять путей пятью строками, а + одной строкой.

find /root/work -name '*.txt' -exec echo {} \;
/root/work/docs/readme.txt
/root/work/docs/guide.txt
/root/work/report.txt
/root/work/my notes.txt
/root/work/empty.txt
find /root/work -name '*.txt' -exec echo {} +
/root/work/docs/readme.txt /root/work/docs/guide.txt /root/work/report.txt /root/work/my notes.txt /root/work/empty.txt

Команды, принимающие несколько путей, например ls, группируйте через +, чтобы сократить число запусков. Размер трёх файлов больше 1k мы проверили одним ls -lh.

find /root/work -type f -size +1k -exec ls -lh {} +
-rw-r--r-- 1 root root 4.9K Oct  5 14:10 /root/work/docs/guide.txt
-rw-r--r-- 1 root root 2.0M Oct  5 14:10 /root/work/logs/app.log
-rw-r--r-- 1 root root 1.2K Oct  5 14:10 /root/work/report.txt

-exec нужен и для массовой настройки прав веб-папки: 644 для файлов и 755 для папок. Перед запуском мы поискали файлы с другими значениями, и появились run.sh и my notes.txt.

find /root/work -type f ! -perm 644
/root/work/run.sh
/root/work/my notes.txt

У файлов и папок разные права, поэтому запускайте отдельно с -type f и -type d. chmod тоже принимает несколько путей, поэтому мы закончили через +.

find /root/work -type f -exec chmod 644 {} +
find /root/work -type d -exec chmod 755 {} +

Повторный поиск с тем же условием ничего не дал, а папка backup, заранее изменённая на 700, тоже получила 755.

Однако run.sh тоже стал 644, и при запуске появилось [Permission denied]. В папках с исполняемыми файлами верните этим файлам право на выполнение через chmod +x.

Чтобы менять только файлы во вложенных папках, добавьте -mindepth 2. С 660 изменились только пять файлов в docs и logs, а после проверки мы вернули 644.

find /root/work -mindepth 2 -type f -exec chmod 660 {} +
find /root/work -type f -perm 660
/root/work/docs/readme.txt
/root/work/docs/guide.txt
/root/work/docs/old.tmp
/root/work/logs/app.log
/root/work/logs/cache.tmp

Связка find и grep ищет по содержимому файла, а не по имени. Чтобы смоделировать проверку веб-шеллов, мы создали четыре файла PHP в отдельной папке /root/site и добавили строку [base64_decode] в html-cache.php и photo.php в папке upload.

find /root/site -type f
/root/site/lib/func.php
/root/site/upload/html-cache.php
/root/site/upload/photo.php
/root/site/index.php

Если имя веб-шелла известно, ищите через -name. С -maxdepth 2, чтобы спуститься только до папки загрузок, появился только html-cache.php.

find /root/site -maxdepth 2 -type f -name 'html*.php'
/root/site/upload/html-cache.php

photo.php с обычным именем здесь не появился. grep -l через -exec выводит только пути файлов со строкой, и появились оба файла.

find /root/site -name '*.php' -exec grep -l 'base64_decode' {} +
/root/site/upload/html-cache.php
/root/site/upload/photo.php

[base64_decode] это функция, которая есть и в файлах ядра WordPress, поэтому откройте найденные файлы и проверьте содержимое перед удалением.

-print0 ставит между путями нулевой символ вместо перевода строки. Нулевой символ не виден на экране, поэтому пути вышли слитно в одну строку.

find /root/work -name '*.txt' -print0
/root/work/docs/readme.txt/root/work/docs/guide.txt/root/work/report.txt/root/work/my notes.txt/root/work/empty.txt

Чтобы передать другой команде имена с пробелами вроде my notes.txt без разрыва, вывод -print0 используют в паре с xargs -0 (по странице man).

6️⃣ Удаление файлов через find и опции

  • ↪️ -delete и -exec rm

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

find /root/work -name '*.tmp'
/root/work/docs/old.tmp
/root/work/logs/cache.tmp

-exec rm {} \; запускает rm для каждого найденного файла. Запуск только в папке logs удалил cache.tmp, и остался только app.log.

find /root/work/logs -name '*.tmp' -exec rm {} \;
ls /root/work/logs
app.log

-delete заставляет find удалять напрямую, без запуска rm. При запуске ничего не вывелось, а повторный поиск с тем же условием файлов .tmp уже не нашёл.

find /root/work -name '*.tmp' -delete
find /root/work -name '*.tmp'

-delete обязательно пишется после условий. find вычисляет командную строку с начала как одно выражение, поэтому с -delete в самом начале он пытается удалить всё под начальным путём, ещё не посмотрев на условия (по странице man).

🔲 Опции команды find

📌 Основные опции: результаты из этой статьи

ОпцияНазначениеРезультат в этой статье
-nameНаходит имена, подходящие под шаблон (учитывает регистр)'*.txt' даёт пять файлов, 'readme*' только docs/readme.txt
-inameСравнивает имена без учёта регистра'readme*' даёт docs/readme.txt и README.md
-type f, -type dОставляет только обычные файлы (f) или папки (d)-type d даёт четыре папки с начальным путём, -type f десять файлов
-maxdepthСпускается только на N уровней под начальный путь-maxdepth 1 оставляет только пять файлов прямо под /root/work
-mindepthПропускает уровни выше N от начального пути-mindepth 2 даёт только пять файлов во вложенных папках
-sizeИщет по размеру (+ больше, - меньше, единицы c, k, M, G)-size +1k даёт три файла, -size -1k только empty.txt
-mtimeСравнивает время с изменения содержимого в единицах по 24 часа-mtime -1 даёт пять файлов, -mtime +7 два файла .tmp
-mminСравнивает время с изменения в минутах-mmin -60 даёт те же пять файлов, что и -mtime -1
-ctimeСравнивает в единицах по 24 часа вплоть до смены данных файла, например прав и имени-ctime -1 даёт все десять тестовых файлов
-newerНаходит то, что изменено позже опорного файлаПять файлов с README.md, заданным на 3 дня назад, в роли опорного
-emptyНаходит файлы размером 0 и пустые папкиДаёт пустую папку backup и empty.txt
-permИщет по правам (только число: ровно это значение, - впереди: все указанные, / впереди: хотя бы одно)-perm 644 даёт восемь файлов, -perm -u+x даёт run.sh, а -perm /6000 после SUID даёт run.sh
-userФильтрует по имени владельцаС -name '*.log' даёт app.log, несуществующая учётная запись завершается ошибкой
-nouserНаходит то, для UID владельца чего нет учётной записиДаёт guide.txt с UID, изменённым на 1500
-nogroupНаходит то, для GID группы чего нет группыДаёт guide.txt с GID, изменённым на 1500
-oОставляет то, что подходит под одно из двух (в скобках вместе с другими условиями)Группировка .log и .tmp даёт три файла
!Обращает условие сразу после негоДаёт пять файлов, не являющихся .txt
-execЗапускает команду после него для каждого найденного файла (путь вместо {})С + в конце один echo выводит пять путей одной строкой
-print0Ставит между путями нулевой символ вместо перевода строкиНулевой символ не виден, пути идут слитно в одну строку
-deletefind сам удаляет найденные файлы (пишется после условий)Ничего не вывелось, повторный поиск не нашёл файлов .tmp

📎 Другие опции: по официальному руководству

ОпцияНазначение
-LСледует по символическим ссылкам и использует данные целевого файла
-pathСравнивает весь путь, а не имя, с шаблоном оболочки
-regexСравнивает весь путь с регулярным выражением
-iregexСравнивает как -regex, но без учёта регистра
-atimeСравнивает время с последнего доступа в единицах по 24 часа
-cnewerНаходит то, чей статус сменился позже времени изменения опорного файла
-groupФильтрует по имени группы-владельца
-xdevНе спускается в папки других файловых систем
-daystartСчитает условия времени с 0 часов сегодня, а не от 24 часов назад
-pruneЕсли это папка, не спускается в неё
-quitСразу завершает работу (-print -quit выводит только первый результат)
-printfВыводит в заданном вами формате
-lsВыводит найденные файлы в формате ls -dils
-fprintСохраняет найденные пути в указанный файл вместо экрана
-okРаботает как -exec, но сначала спрашивает
-execdirРаботает как -exec, но запускает команду в папке найденного файла

🔲 Симулятор команды find

Симулятор ниже это виртуальный сервер с той же тестовой папкой, где можно самим выполнять условия -name, -type, -size, -mtime, -perm, а также -exec и -delete.

Симулятор команды findfindutils 4.8
[root@server work]#
Этот виртуальный сервер работает только в браузере, а в левой колонке показаны размер, время изменения и права каждого файла в /root/work. Файлы, удалённые через -delete или -exec rm, восстанавливаются кнопкой [Сначала].

7️⃣ Ошибки команды find

  • ↪️ paths must precede expression и Permission denied

Если написать шаблон без кавычек, оболочка применяет правила для Подстановочные знаки и сначала раскрывает его в имена файлов текущей папки. Когда мы перешли в папку docs и написали *.txt без кавычек, оболочка передала два имени guide.txt и readme.txt, и появилась ошибка ниже.

cd /root/work/docs
find /root/work -name *.txt
find: paths must precede expression: `readme.txt'
find: possible unquoted pattern after predicate `-name'?

Код выхода был 1.

Без \; или + в конце -exec появилось [missing argument to `-exec’].

find /root/work -name '*.log' -exec ls -l {}
find: missing argument to `-exec'

Несуществующий начальный путь даёт [No such file or directory] и завершается с кодом выхода 1.

find /nonexistent-dir -name x
find: '/nonexistent-dir': No such file or directory

Несуществующее имя учётной записи в -user или значение -type, отличное от заданных букв вроде f и d, сразу завершаются ошибкой, и поиск не начинается.

find /root/work -user nosuchuser
find: 'nosuchuser' is not the name of a known user
find /root/work -type x
find: Unknown argument to -type: x

Под обычной учётной записью на сервере Debian 12 мы изменили права папки lock в тестовой папке на 000 и выполнили поиск по тестовой папке. Содержимое lock не читалось, появилось [Permission denied], и код выхода был 1.

find ~/findtest
/home/user/findtest
/home/user/findtest/report.txt
/home/user/findtest/lock
find: '/home/user/findtest/lock': Permission denied
/home/user/findtest/docs
/home/user/findtest/docs/readme.txt

Чтобы скрыть только строки ошибок, добавьте 2>/dev/null. Текст ошибки исчез, но код выхода остался 1.

find ~/findtest -name '*.txt' 2>/dev/null
/home/user/findtest/report.txt
/home/user/findtest/docs/readme.txt

🔢 FAQ & рекомендуемые материалы

find при каждом запуске сам обходит всё под начальным путём. locate ищет имена в базе данных, заранее созданной updatedb, поэтому файлы, созданные после последнего обновления базы, не появляются (по странице man).

-mtime смотрит на время изменения содержимого, а -ctime и на смену данных файла, например прав и имени. Даже у README.md, которому через touch -d задали время изменения 3 дня назад, сама эта операция считается сменой данных, поэтому -ctime -1 показал все десять тестовых файлов.

ℹ️ О партнёрских ссылках
Материалы этого сайта содержат партнёрские ссылки. Если посетитель покупает товар или услугу по такой ссылке, сайт получает комиссию от продавца. При этом сумма, которую платит покупатель (при акционных скидках сумма снижается ↓), не увеличивается. Указанные цены, скидки и наличие актуальны на момент написания и могут отличаться, поэтому перед покупкой уточняйте их у продавца. Товары выбираются и оцениваются по нашим собственным критериям, а комиссия не влияет ни на порядок, ни на содержание обзоров.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *

Докажите, что вы человек: 3   +   1   =