How to run a shell script when a file or directory

2019-01-04 21:40发布

I want to run a shell script when a specific file or directory changes.

How can I easily do that?

10条回答
Emotional °昔
2楼-- · 2019-01-04 22:18

Example of using inotifywait:

Suppose I want to run rails test every time I modify a relevant file.

1. Make a list of the relevant files you want to watch:

You could do it manually, but I find ack very helpful to make that list.

ack --type-add=rails:ext:rb,erb --rails -f > Inotifyfile

2. Ask inotifywait to do the job

while inotifywait --fromfile Inotifyfile; do rails test; done

That's it!

NOTE: In case you use Vagrant to run the code on a VM, you might find useful the mhallin/vagrant-notify-forwarder extension.

UPDATE: Even better, make an alias and get rid of the file:

alias rtest="while inotifywait $(ack --type-add=rails:ext:rb,erb --rails -f | tr \\n \ ); do rails test; done"
查看更多
一夜七次
3楼-- · 2019-01-04 22:19

Check out the kernel filesystem monitor daemon

http://freshmeat.net/projects/kfsmd/

Here's a how-to:

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

查看更多
Emotional °昔
4楼-- · 2019-01-04 22:20

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).

#!/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
查看更多
太酷不给撩
5楼-- · 2019-01-04 22:23
三岁会撩人
6楼-- · 2019-01-04 22:25

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 .

查看更多
Emotional °昔
7楼-- · 2019-01-04 22:27

Just for debugging purposes, when I write a shell script and want it to run on save, I use this:

#!/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:

"$(ls -lT $file | awk '{ print $8 }')"
查看更多
登录 后发表回答