Как запустить сценарий оболочки при изменении файла или каталога?


Я хочу запустить сценарий оболочки при изменении конкретного файла или каталога.

Как я могу легко сделать это?

9 51

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/

вот как:

http://www.linux.com/archive/feature/124903

Как уже упоминалось, 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
}