Как запустить сценарий оболочки при изменении файла или каталога?
Я хочу запустить сценарий оболочки при изменении конкретного файла или каталога.
Как я могу легко сделать это?
9 ответов:
использовать inotify-tools.
Я использую этот скрипт для запуска скрипта сборки при изменениях в дереве каталогов:
#! /bin/bash DIRECTORY_TO_OBSERVE="js" // might want to change this function block_for_change { inotifywait -r \ -e modify,move,create,delete \ $DIRECTORY_TO_OBSERVE } BUILD_SCRIPT=build.sh // might want to change this too function build { bash $BUILD_SCRIPT } build while block_for_change; do build done
использует
inotify-tools
. Проверьтеinotifywait
на странице как настроить то, что запускает сборку.
вы можете попробовать
entr
инструмент для запуска произвольных команд при изменении файлов. Пример для файлов:$ ls -d * | entr sh -c 'make && make test'
или:
$ ls *.css *.html | entr reload-browser Firefox
для каталогов использовать
-d
, но вы должны использовать его в цикле, например:while true; do find path/ | entr -d echo Changed; done
или:
while true; do ls path/* | entr -pd echo Changed; done
Проверьте демон монитора файловой системы ядра
http://freshmeat.net/projects/kfsmd/
вот как:
Как уже упоминалось, inotify-tools, вероятно, лучшая идея. Однако, если вы программируете для удовольствия, вы можете попробовать и заработать hacker XPs разумным применением хвост-f .
вот еще один вариант:http://fileschanged.sourceforge.net/
см. особенно "пример 4", который"отслеживает каталог и архивирует любые новые или измененные файлы".
Как насчет такого сценария? Использует команду 'stat' для получения времени доступа к файлу и выполняет команду всякий раз, когда происходит изменение времени доступа (при каждом доступе к файлу).
#!/bin/bash while true do ATIME=`stat -c %Z /path/to/the/file.txt` if [[ "$ATIME" != "$LTIME" ]] then echo "RUN COMMNAD" LTIME=$ATIME fi sleep 5 done
только для целей отладки, Когда я пишу сценарий оболочки и хочу, чтобы он работал на save, я использую это:
#!/bin/bash file="" # Name of file command="${*:2}" # Command to run on change (takes rest of line) t1="$(ls --full-time $file | awk '{ print }')" # Get latest save time while true do t2="$(ls --full-time $file | awk '{ print }')" # Compare to new save time if [ "$t1" != "$t2" ];then t1="$t2"; $command; fi # If different, run command sleep 0.5 done
запустить его как
run_on_save.sh myfile.sh ./myfile.sh arg1 arg2 arg3
изменить: выше протестировано на Ubuntu 12.04, для Mac OS, измените строки ls на:
"$(ls -lT $file | awk '{ print }')"
добавить следующее в~/.bashrc следующее:
function react() { if [ -z "" -o -z "" ]; then echo "Usage: react <[./]file-to-watch> <[./]action> <to> <take>" elif ! [ -r "" ]; then echo "Can't react to , permission denied" else TARGET=""; shift ACTION="$@" while sleep 1; do ATIME=$(stat -c %Z "$TARGET") if [[ "$ATIME" != "${LTIME:-}" ]]; then LTIME=$ATIME $ACTION fi done fi }