Я хочу автоматически запускать сценарий всякий раз, когда новые файлы копируются в определенный каталог. Другими словами, есть ли в 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
и подстановка процесса (<(...)
) важны при запуске из диспетчера процессов, чтобы правильно обрабатывать сигнализацию (т.е. чтобы убрать оболочку с пути).