find — что это и зачем
find — стандартная команда Linux для поиска файлов и каталогов по имени, типу, правам, размеру, дате и десяткам других критериев. С помощью `-exec` поверх найденного можно сразу выполнять команды. Универсальный инструмент админа для массовой работы с файловой системой.
find
find — стандартная команда Linux для поиска файлов и каталогов по имени, типу, правам, размеру, дате и десяткам других критериев. С помощью -exec поверх найденного можно сразу выполнять команды. Универсальный инструмент админа для массовой работы с файловой системой.
Что это в одном абзаце
find рекурсивно обходит каталог и для каждого файла проверяет набор условий. Если условия совпадают — файл попадает в вывод (или над ним выполняется команда). В отличие от ls, find ищет вглубь и умеет фильтровать по любым атрибутам файла — это его суперсила.
find . -name "*.log" # все файлы .log в текущем каталоге
find / -type d -name "node_modules" # все папки node_modules в системе
find /var/log -mtime -1 # файлы в /var/log изменённые за последние сутки
find . -size +100M # файлы больше 100 МБ
Базовая структура: find <откуда> <условия> <действие>. Без действия по умолчанию — -print (вывести путь).
Базовые фильтры
-name "pattern"— по имени с шеллглобом (*,?,[abc]). Чувствительно к регистру.-iname "pattern"— то же без учёта регистра.-type f— обычные файлы,-type d— каталоги,-type l— симлинки.-size +100M— больше 100 МБ.+— больше,-— меньше, без знака — ровно. Единицы:c(байт),k,M,G.-mtime -7— изменён менее 7 суток назад.+7— старше 7 суток.-mmin -30— то же в минутах.-user alice/-group devs— по владельцу/группе.-perm 644/-perm -u+w— по правам (точно или по битам).-empty— пустые файлы и каталоги.
Условия можно объединять:
find /var/log -type f -name "*.log" -mtime +30
# .log-файлы старше 30 дней в /var/log
По умолчанию между условиями стоит логическое И. Для ИЛИ используется -o со скобками:
find . \( -name "*.tmp" -o -name "*.cache" \) -delete
Скобки экранируем через \( и \) — иначе шелл их съест.
Действия (что сделать с найденным)
-print— вывести путь (действие по умолчанию).-print0— вывести с разделителем\0вместо\n(безопасно для имён с пробелами).-delete— удалить.-exec <команда> {} \;— выполнить команду над каждым файлом.{}— путь к файлу.-exec <команда> {} +— то же, но передать сразу пачку файлов одной команде (быстрее).-ok <команда> {} \;— то же, но с подтверждением каждого вызова.
# Удалить все .pyc в проекте
find . -name "*.pyc" -delete
# Сменить права у всех .sh на 755
find /opt/myapp -name "*.sh" -exec chmod 755 {} +
# Сжать все .log старше недели
find /var/log -name "*.log" -mtime +7 -exec gzip {} +
Разница \; vs + критична. \; запустит команду один раз на каждый файл — на тысячах файлов это медленно. + соберёт пачку и запустит команду один раз с пачкой как аргументами — быстро. Используйте +, когда команда поддерживает несколько файлов (как chmod, gzip, rm).
Типичные одностроки админа
Найти большие файлы, чтобы освободить место:
find / -xdev -type f -size +100M -exec ls -lh {} + | sort -k 5 -h
-xdev — не уходить на смонтированные ФС (не лезть в /proc, /sys, /run, чужие диски).
Найти файлы изменённые за последний час (отладка инцидента):
sudo find /etc -mmin -60
Удалить пустые каталоги:
find /tmp/build -type d -empty -delete
Найти файлы с SUID-битом (классический аудит безопасности):
sudo find / -xdev -perm -4000 -type f 2>/dev/null
Заменить владельца у всех файлов в каталоге, кроме определённого пользователя:
sudo find /var/www/site -type f ! -user www-data -exec chown www-data:www-data {} +
Подробно про права и владельцев — chmod и chown.
Грабли find
- Пробелы в именах. Стандартный
find ... | xargsломается на файлах с пробелами. Решение: либо-print0+xargs -0, либо сразу-exec ... +. - Скрытые каталоги.
find . -name "*.tmp"найдёт и.git/...если внутри есть.tmp. Чтобы пропускать:find . -path '*/.git' -prune -o -name "*.tmp" -print. -mtimeнепривычно работает.-mtime 0— изменён за последние 24 часа,-mtime 1— между 24 и 48 часами назад,-mtime +7— старше 7 суток. Думайте в днях с округлением вниз.-deleteопасный.find / -name "*.log" -deleteбез проверки удалит больше, чем хотелось. Сначала запускайте без-delete(только-print), убедитесь в списке, потом добавляйте-delete.
Альтернативы find
locate(mlocate/plocate) — мгновенный поиск по индексу, обновляемому раз в сутки. Удобно для «где же лежит этот файл», когда полное имя помнишь. Установить:sudo apt install plocate.fd— современный аналог find с человеческим CLI:fd '\.log$' /var/log. Установить:sudo apt install fd-find.fzf— fuzzy-finder с интерактивным выбором. Часто комбинируют:find . | fzf.
В скриптах автоматизации остаётся find — он стандартен и работает на любой UNIX-системе. fd хорош как desktop-инструмент.
Частые вопросы
Что такое find в Linux
Стандартная команда поиска файлов и каталогов по разным критериям: имя, тип, права, размер, дата изменения. В отличие от ls, find рекурсивно обходит каталоги и умеет выполнять команды над найденным через -exec. Базовая утилита для admin-задач.
Чем find отличается от locate
find ищет в реальном времени, обходя файловую систему. Это медленнее, но всегда актуально. locate ищет по предварительно построенному индексу (updatedb раз в сутки) — мгновенно, но может пропустить файлы, созданные за последний час. find гибче (десятки фильтров), locate быстрее (только по имени).
Как найти файлы изменённые за последний час
find /path -mmin -60 — изменённые за последние 60 минут. Для часов — нужно считать через -mmin, ключа -mh нет. Для дней есть -mtime -1 (последние 24 часа). Для отладки инцидентов часто полезно sudo find /etc -mmin -60 — показывает, что админ менял в последний час.
Как удалить старые логи через find
find /var/log -name "*.log" -mtime +30 -type f -delete — удалит обычные .log-файлы старше 30 дней. Перед -delete запустите без него (с дефолтным -print), посмотрите список — и только потом добавляйте -delete. Альтернатива — настроить logrotate, который сделает то же самое более грамотно.
Что такое find -exec
Действие, которое выполняет команду над каждым найденным файлом. Синтаксис: -exec <команда> {} \; (один файл за вызов) или -exec <команда> {} + (пачка файлов одной командой). Второй вариант быстрее на больших объёмах. {} — это плейсхолдер для пути к файлу.
Почему find не находит файлы с пробелами в именах
Сама команда find их находит без проблем. Проблемы начинаются при пайпе в xargs: find ... | xargs rm ломается на файлах вида my file.txt — xargs делит вход по пробелам. Решение: find ... -print0 | xargs -0 rm (нулевой разделитель) или find ... -exec rm {} + (без xargs вовсе).
Что почитать
- chmod —
find -exec chmodстандартный приём для массовой смены прав в каталоге. - chown —
find -exec chown— типичный шаг при разворачивании сайта. - bash if/else —
findчасто используется в скриптах вместе с условиями:if find ... -name foo.