Как автоматически запустить скрипт, когда содержимое каталога меняется в Linux?
17
Я хочу автоматически запускать скрипт всякий раз, когда новые файлы копируются в определенный каталог. Другими словами, есть ли способ в Linux «наблюдать» каталог за изменениями, а затем запускать что-то в ответ на изменения?
Если вам повезет , достаточно , чтобы быть на распределении DEBiAN на основе apt-get install dnotify. Другие дистрибутивы, вероятно, имеют что-то похожее - ищите dnotifyназвание.
dnotify - простая программа, основанная на ядре Linux 2.4.19 + API dnotify. Команда dnotify может выполнять указанную команду каждый раз, когда изменяется содержимое определенного каталога. Он запускается из командной строки и принимает два аргумента: один или несколько каталогов для мониторинга и команду, выполняемую при каждом изменении каталога. Параметры определяют, какие события вызывать: когда файл был прочитан в каталоге, когда он был создан, удален и т. Д.
Если вы хотите обрабатывать это в своей собственной программе, dnotify также является API, который вы хотите использовать.
@MikeB, после того, как Googling dnotify вы предложили, я вместо этого использовал inotify, который явно превосходит его. Спасибо, что указали мне правильное направление. apt-get install inotify-tools
GeneQ
7
@GeneQ, inotify заменил dnotify.
Дэвид
1
Аналогично на Gentoo:emerge inotify-tools
Джеймс Снирингер
Да, я хотел сказать, что ядро 2.4.19 довольно древнее ;-) inotify - это путь.
Дэвид З
Ах да ... Я забыл, что было более новым :)
MikeyB
12
Вы можете запустить скрипт с помощью инструментов inotify, что-то вроде этого. Он будет отслеживать каталог на наличие изменений в измененных файлах, новых файлах и удаленных файлах, а затем выполнит сценарий.
#!/bin/sh
while inotifywait -e modify -e create -e delete /home/me/code; do
rsync [options] /home/me/code/ /media/nfs/code/
done
Просто учтите, что если исходный каталог изменяется во время его копирования, inotifywait НЕ будет его видеть, и эти изменения не будут скопированы до тех пор, пока не будут произведены дальнейшие изменения после завершения копирования. Вероятно, не проблема, хотя.
Рауль Салинас-Монтеагудо
Как вы можете запустить это в режиме демона?
Крис Ф
4
я думаю, incron - это то, что вы хотите. Он использует inotify в качестве механизма уведомления (который, как указали другие, заменяет dnotify), но не требует скрипта, который выполняется постоянно с использованием inotifywait или аналогичного (хотя, очевидно, демон incron работает все время). Общесистемные 'crontabs' и пользовательские 'crontabs' поддерживаются аналогично стандартному cron, но вместо указания времени в качестве триггеров используются события inotify и имена файлов / каталогов.
Incron упакован для многих дистрибутивов, включая Ubuntu и Debian, я считаю.
entr - это самый простой и составной инструмент для уведомления о файлах, который я когда-либо видел. Его использование оптимизировано для просмотра файлов, а не каталогов, но оно также может решить вашу проблему.
Чтобы обнаружить и обработать добавленный файл, объедините его с другими инструментами, такими как, например 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 , runit , systemd или sysvinit и пропустите цикл:
Ответы:
Если вам повезет , достаточно , чтобы быть на распределении DEBiAN на основе
apt-get install dnotify
. Другие дистрибутивы, вероятно, имеют что-то похожее - ищитеdnotify
название.Если вы хотите обрабатывать это в своей собственной программе, dnotify также является API, который вы хотите использовать.
источник
emerge inotify-tools
Вы можете запустить скрипт с помощью инструментов inotify, что-то вроде этого. Он будет отслеживать каталог на наличие изменений в измененных файлах, новых файлах и удаленных файлах, а затем выполнит сценарий.
источник
я думаю, incron - это то, что вы хотите. Он использует inotify в качестве механизма уведомления (который, как указали другие, заменяет dnotify), но не требует скрипта, который выполняется постоянно с использованием inotifywait или аналогичного (хотя, очевидно, демон incron работает все время). Общесистемные 'crontabs' и пользовательские 'crontabs' поддерживаются аналогично стандартному cron, но вместо указания времени в качестве триггеров используются события inotify и имена файлов / каталогов.
Incron упакован для многих дистрибутивов, включая Ubuntu и Debian, я считаю.
источник
Для этой цели есть программа, autoenv. Вы можете проверить это.
источник
entr - это самый простой и составной инструмент для уведомления о файлах, который я когда-либо видел. Его использование оптимизировано для просмотра файлов, а не каталогов, но оно также может решить вашу проблему.
Чтобы обнаружить и обработать добавленный файл, объедините его с другими инструментами, такими как, например
make
.entr
не отправляет имя или что-то в этом роде, оно просто запускает то, что вы сказали, чтобы оно запускалось.Чтобы проверить наличие добавленных файлов в каталоге:
Если вы также хотите действовать при изменении существующего файла:
... и вот тут вам пригодится механизм цикла, так как
find
выражение будет запущено снова, если файл будет добавлен.Если вам нужна лучшая обработка ошибок и вы хотите, чтобы все выполнялось только один раз для каждого добавленного / удаленного файла, все становится немного странным, но для этих простых случаев это замечательно.
РЕДАКТИРОВАТЬ: Если вы хотите сделать это на системном уровне, что-то вроде incron , просто добавьте скрипт в ваш любимый менеджер процессов (например, s6 , runit , systemd или sysvinit и пропустите цикл:
Функция
exec
и замена процесса (<(...)
) важны при запуске из диспетчера процессов для правильной обработки сигналов (т. Е. Для удаления оболочки).источник