I want to run a shell script when a specific file or directory changes.
当特定文件或目录发生更改时,我希望运行shell脚本。
How can I easily do that?
我怎么能轻易做到呢?
9 个解决方案
#2
18
I use this script to run a build script on changes in a directory tree:
我使用这个脚本在目录树中的更改上运行一个构建脚本:
#! /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
Uses inotify-tools
. Check inotifywait
man page for how to customize what triggers the build.
使用inotify-tools。检查inotifywait man页面,了解如何自定义触发构建的因素。
#3
11
You may try entr
tool to run arbitrary commands when files change. Example for files:
当文件发生变化时,您可以尝试使用entr工具来运行任意命令。文件的例子:
$ ls -d * | entr sh -c 'make && make test'
or:
或者:
$ ls *.css *.html | entr reload-browser Firefox
For directories use -d
, but you've to use it in the loop, e.g.:
对于使用-d的目录,但是必须在循环中使用,例如:
while true; do find path/ | entr -d echo Changed; done
or:
或者:
while true; do ls path/* | entr -pd echo Changed; done
#4
3
Check out the kernel filesystem monitor daemon
检查内核文件系统监控守护进程
http://freshmeat.net/projects/kfsmd/
http://freshmeat.net/projects/kfsmd/
Here's a how-to:
这里有一个指南:
http://www.linux.com/archive/feature/124903
http://www.linux.com/archive/feature/124903
#5
2
As mentioned, inotify-tools is probably the best idea. However, if you're programming for fun, you can try and earn hacker XPs by judicious application of tail -f .
如前所述,inotify-tools可能是最好的方法。但是,如果您是为了好玩而编程,您可以尝试通过明智地应用tail -f来获得黑客XPs。
#6
1
Here's another option: http://fileschanged.sourceforge.net/
这是另一种选择:http://fileschanged.sourceforge.net/
See especially "example 4", which "monitors a directory and archives any new or changed files".
请参见“示例4”,它“监视目录并归档任何新的或已更改的文件”。
#7
0
How about this script? Uses the 'stat' command to get the access time of a file and runs a command whenever there is a change in the access time (whenever file is accessed).
这个脚本呢?使用“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
#8
0
Just for debugging purposes, when I write a shell script and want it to run on save, I use this:
出于调试目的,当我编写shell脚本并希望它在save上运行时,我使用以下方法:
#!/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 it as
运行它
run_on_save.sh myfile.sh ./myfile.sh arg1 arg2 arg3
Edit: Above tested on Ubuntu 12.04, for Mac OS, change the ls lines to:
编辑:以上在Ubuntu 12.04上测试过,对于Mac OS,将ls改为:
"$(ls -lT $file | awk '{ print $8 }')"
#9
0
Add the following to ~/.bashrc:
向~/.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
}
#1
#2
18
I use this script to run a build script on changes in a directory tree:
我使用这个脚本在目录树中的更改上运行一个构建脚本:
#! /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
Uses inotify-tools
. Check inotifywait
man page for how to customize what triggers the build.
使用inotify-tools。检查inotifywait man页面,了解如何自定义触发构建的因素。
#3
11
You may try entr
tool to run arbitrary commands when files change. Example for files:
当文件发生变化时,您可以尝试使用entr工具来运行任意命令。文件的例子:
$ ls -d * | entr sh -c 'make && make test'
or:
或者:
$ ls *.css *.html | entr reload-browser Firefox
For directories use -d
, but you've to use it in the loop, e.g.:
对于使用-d的目录,但是必须在循环中使用,例如:
while true; do find path/ | entr -d echo Changed; done
or:
或者:
while true; do ls path/* | entr -pd echo Changed; done
#4
3
Check out the kernel filesystem monitor daemon
检查内核文件系统监控守护进程
http://freshmeat.net/projects/kfsmd/
http://freshmeat.net/projects/kfsmd/
Here's a how-to:
这里有一个指南:
http://www.linux.com/archive/feature/124903
http://www.linux.com/archive/feature/124903
#5
2
As mentioned, inotify-tools is probably the best idea. However, if you're programming for fun, you can try and earn hacker XPs by judicious application of tail -f .
如前所述,inotify-tools可能是最好的方法。但是,如果您是为了好玩而编程,您可以尝试通过明智地应用tail -f来获得黑客XPs。
#6
1
Here's another option: http://fileschanged.sourceforge.net/
这是另一种选择:http://fileschanged.sourceforge.net/
See especially "example 4", which "monitors a directory and archives any new or changed files".
请参见“示例4”,它“监视目录并归档任何新的或已更改的文件”。
#7
0
How about this script? Uses the 'stat' command to get the access time of a file and runs a command whenever there is a change in the access time (whenever file is accessed).
这个脚本呢?使用“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
#8
0
Just for debugging purposes, when I write a shell script and want it to run on save, I use this:
出于调试目的,当我编写shell脚本并希望它在save上运行时,我使用以下方法:
#!/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 it as
运行它
run_on_save.sh myfile.sh ./myfile.sh arg1 arg2 arg3
Edit: Above tested on Ubuntu 12.04, for Mac OS, change the ls lines to:
编辑:以上在Ubuntu 12.04上测试过,对于Mac OS,将ls改为:
"$(ls -lT $file | awk '{ print $8 }')"
#9
0
Add the following to ~/.bashrc:
向~/.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
}