Автоматизация workflows с inotifywait: Реактивные скрипты для разработчиков на Linux

Система inotify в ядре Linux предоставляет механизм для отслеживания изменений в файловой системе в реальном времени. Для разработчиков это открывает возможности создания реактивных скриптов, автоматизирующих задачи вроде пересборки проектов, запуска тестов или синхронизации конфигов. Разберём практическое применение утилиты inotifywait из пакета inotify-tools в Arch Linux.

Установка и базовый мониторинг

Установите пакет через pacman:

bash
sudo pacman -S inotify-tools

Проверим отслеживание изменений в директории проектов:

bash
inotifywait -m -r -e modify,create,delete ~/projects/

Флаги:

  • -m: непрерывный мониторинг (не завершать после первого события)
  • -r: рекурсивный обход поддиректорий
  • -e: фильтр событий (здесь: модификация, создание, удаление)

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

text
/home/user/projects/app/ CODE/module.js MODIFY

Автоматизация сборки TypeScript

Создадим скрипт build-watcher.sh, перекомпилирующий проект при изменениях:

bash
#!/bin/bash
DIR="/path/to/typescript/project"

while true; do
  inotifywait -qq -e modify -r "$DIR/src" "$DIR/tsconfig.json"
  echo "$(date): Changes detected. Rebuilding..."
  npm run build
done

Особенности:

  • -qq подавляет вывод除了 критических ошибок
  • Цикл while true восстанавливает наблюдатель после каждого события
  • Явное указание tsconfig.json гарантирует реакцию на изменение конфигурации

Запустите скрипт в фоне:

bash
chmod +x build-watcher.sh
./build-watcher.sh > build.log 2>&1 &

Системные ограничения и оптимизация

Inotify имеет лимиты на количество отслеживаемых файлов. Проверьте текущие значения:

bash
sysctl fs.inotify.max_user_instances
sysctl fs.inotify.max_user_watches

Для проектов с тысячами файлов увеличьте лимиты временно:

bash
sudo sysctl -w fs.inotify.max_user_watches=524288

Постоянные настройки создайте в /etc/sysctl.d/40-inotify.conf:

text
fs.inotify.max_user_watches=524288
fs.inotify.max_user_instances=1024

Интеграция с systemd для production

Для серверных приложений полезно автоматизировать перезапуск служб при изменении конфигов. Создаём юнит /etc/systemd/system/config-watcher.service:

ini
[Unit]
Description=Reload service on config change

[Service]
ExecStart=/usr/local/bin/watch-config.sh
Restart=always

[Install]
WantedBy=multi-user.target

Скрипт /usr/local/bin/watch-config.sh:

bash
#!/bin/bash
CONFIG_DIR="/etc/myapp/conf.d"

inotifywait -m -e modify "$CONFIG_DIR" |
while read -r path action file; do
  echo "Reloading systemd due to changes in $file"
  systemctl restart myapp.service
done

Нюансы:

  • Используйте modify вместо close_write для совместимости с разными редакторами
  • Каскадные перезагрузки предотвращаются через Debounce-таймеры в реальных сценариях

Отладка и расширенные сценарии

Для анализа шаблонов изменений добавьте фильтрацию по расширениям:

bash
inotifywait -m --format '%w%f' -e create ~/downloads/ |
grep -E '\.(zip|deb)$' |
while read file; do
  echo "New archive: $file"
done

Ключевые параметры:

  • --format кастомизирует вывод
  • --exclude игнорирует временные файлы (например, .*.swp)
  • --timeout для периодического выполнения фоновых задач

Альтернативы и когда их использовать

Хотя inotifywait идеален для мгновенной реакции, для сложных задач рассмотрите:

  • entr - перезапуск команд по изменениям с лаконичным синтаксисом
  • systemd.path - нативная интеграция с юнитами systemd
  • fswatch - кроссплатформенное решение с поддержкой событий macOS/Windows

Главное преимущество inotifywait — отсутствие опроса диска (polling), что критично для SSD-накопителей и энергоэффективности на ноутбуках.

Разработчики, внедряющие inotify-решения, должны учитывать race conditions — события могут генерироваться быстрее, чем их обрабатывает скрипт. В production-средах добавляйте очереди задач (например, через Redis) и механизмы подавления дублирующихся событий.

text