Назад | Перейти на главную страницу

Как автоматически запускать скрипт при изменении содержимого каталога в Linux?

Я хочу автоматически запускать сценарий всякий раз, когда новые файлы копируются в определенный каталог. Другими словами, есть ли в Linux способ «наблюдать» за изменениями в каталоге, а затем запускать что-то в ответ на это изменение?

Если вам посчастливилось работать с дистрибутивом на основе Debian, apt-get install dnotify. В других дистрибутивах, вероятно, есть что-то подобное - ищите dnotify название.

dnotify - это простая программа, основанная на API dnotify ядра Linux 2.4.19 +. dnotify может выполнять указанную команду каждый раз при изменении содержимого определенного каталога. Он запускается из командной строки и принимает два аргумента: один или несколько каталогов для мониторинга и команду для выполнения при каждом изменении каталога. Параметры определяют, какие события запускать: когда файл был прочитан в каталоге, когда он был создан, удален и так далее.

Если вы хотите справиться с этим в своей собственной программе, dnotify также является API, который вы хотите использовать.

Вы можете запустить сценарий с помощью inotify-tools, примерно так. Он будет следить за каталогом на предмет изменений в измененных файлах, новых файлах и удаленных файлах, а затем выполнит сценарий.

#!/bin/sh
while inotifywait -e modify -e create -e delete /home/me/code; do
    rsync [options] /home/me/code/ /media/nfs/code/ 
done

Incron я думаю, это в основном то, что вы хотите. Он использует inotify в качестве механизма уведомления (который, как указывали другие, заменяет dnotify), но не требует непрерывного выполнения сценария с использованием inotifywait или аналогичного (хотя, очевидно, демон incron работает все время). Общесистемные crontabs и пользовательские crontab поддерживаются аналогично стандартному cron, но вместо указания времени в качестве триггеров используются события inotify и имена файлов / каталогов.

Я считаю, что incron упакован для многих дистрибутивов, включая Ubuntu и Debian.

Специально для этого есть программное обеспечение, autoenv Возможно, вы захотите это проверить.

вход это самый простой и составной инструмент уведомления о файлах, который я когда-либо видел. Его использование оптимизировано для просмотра файлов, а не каталогов, но оно также может решить ваш случай.

Чтобы обнаружить и обработать добавленный файл, объедините его с другими инструментами, например make. entr не отправляет имя или что-то в этом роде, он просто выполняет то, что вы ему сказали.

Чтобы проверить добавленные файлы в каталог:

## entr exits with rc=0 when terminated
## rc=1 when watched files go away or don't exist to begin with
## rc=2 when new files arrive in watched directories
until echo /path/to/directory_to_watch | entr -d do_stuff
do sleep 1; done

Если вы хотите также действовать при изменении существующего файла:

## Here's why it comes in handy that entr exits when new files are added --
## find gets re-run.
until find /path/to/directory_to_watch/ -path /path/to/directory_to_watch/* |
    entr -d do_stuff
do sleep 1; done

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

Если вам нужна лучшая обработка ошибок и вы хотите, чтобы все запускалось только один раз для каждого добавленного / удаленного файла, все становится немного странно, но для этих простых случаев это великолепно.


РЕДАКТИРОВАТЬ: если вы хотите сделать это на системном уровне, что-то вроде Incronпросто добавьте сценарий в свой любимый диспетчер процессов (например, s6, запустить его, systemd или сисвинит и пропустить цикл:

#!/bin/bash
exec entr -d do_stuff < <(find /path/to/directory_to_watch/ -path /path/to/directory_to_watch/*)

В exec и подстановка процесса (<(...)) важны при запуске из диспетчера процессов, чтобы правильно обрабатывать сигнализацию (т.е. чтобы убрать оболочку с пути).