Иногда нужно отследить появление нового файла в каталоге.
Самый простой вариант:
while true; do
find /var/incoming -type f
sleep 1
done
Работает. Но каждые несколько секунд мы заново обходим каталог, даже если за это время ничего не произошло.
Для событийного мониторинга в Linux есть inotify.
▪️Следим за изменениями без постоянного обхода
Например, с inotifywait:
inotifywait -m /var/incoming
При создании файла можно получить:
/var/incoming/ CREATE report.csv
А с
-e можно ограничить интересующие события:inotifywait -m \
-e create -e moved_to \
/var/incoming
Теперь процесс ждёт события вместо постоянного запуска
find.▪️Можно сразу обрабатывать новые файлы
inotifywait -m -e create -e moved_to --format '%w%f' \
/var/incoming |
while read -r file; do
process "$file"
done
Когда файл появляется или перемещается в каталог, вызывается обработчик.
▪️Почему
polling хужеПри polling:
find → sleep → find → sleep → find
мы постоянно проверяем состояние файловой системы, даже когда ничего не меняется.
При
inotify:wait → event → обработка → waitпроцесс большую часть времени просто ожидает событие.
▪️Но есть важный нюанс
inotify не является очередью событий для бесконечного количества изменений.У ядра есть ограничение на очередь событий:
cat /proc/sys/fs/inotify/max_queued_events
Если приложение не успевает читать события, очередь может переполниться.
Тогда появляется:
IN_Q_OVERFLOW
И приложение уже не может считать, что знает обо всех произошедших изменениях.
Поэтому для критичных систем иногда нужен дополнительный механизм сверки состояния.
▪️Практический сценарий
Есть каталог, куда другой сервис складывает файлы:
/var/incoming/
Вместо постоянного:
find /var/incoming ...
можно реагировать непосредственно на
CREATE или MOVED_TO.Но если файл сначала создаётся и затем постепенно записывается, одного события создания недостаточно.
Нужно учитывать момент, когда файл полностью готов к обработке.
Именно поэтому в production важно следить не только за самим событием, но и за способом передачи файла.
BashTex 📱 #bash #systemd