在Linux中,如何在文件或目录更改时运行shell脚本
我想在特定文件或目录更改时运行一个shell脚本。
我怎么能轻松地做到这一点?
使用inotify-tools 。
我使用这个脚本来对目录树中的更改运行构build脚本:
#! /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
手册页以了解如何自定义触发构build的内容。
当文件改变时,你可以尝试使用工具来运行任意命令。 文件示例:
$ 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
如前所述,inotify-tools可能是最好的主意。 但是,如果您为了获得乐趣而进行编程,则可以通过审慎地应用tail -f来尝试获得黑客XP。
这是另一个选项: http : //fileschanged.sourceforge.net/
特别参见“示例4”,其中“监视目录并存档任何新的或更改的文件”。
只是为了debugging目的,当我编写一个shell脚本,并希望它运行保存,我使用这个:
#!/bin/bash file="$1" # Name of file command="${*:2}" # Command to run on change (takes rest of line) t1="$(ls --full-time $file | awk '{ print $7 }')" # Get latest save time while true do t2="$(ls --full-time $file | awk '{ print $7 }')" # 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上testing,对于Mac OS,将ls行更改为:
"$(ls -lT $file | awk '{ print $8 }')"
将以下内容添加到〜/ .bashrc中:
function react() { if [ -z "$1" -o -z "$2" ]; then echo "Usage: react <[./]file-to-watch> <[./]action> <to> <take>" elif ! [ -r "$1" ]; then echo "Can't react to $1, permission denied" else TARGET="$1"; shift ACTION="$@" while sleep 1; do ATIME=$(stat -c %Z "$TARGET") if [[ "$ATIME" != "${LTIME:-}" ]]; then LTIME=$ATIME $ACTION fi done fi }
这个脚本怎么样? 使用“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