代码之家  ›  专栏  ›  技术社区  ›  Drew LeSueur

如何在文件或目录更改时运行shell脚本?

  •  56
  • Drew LeSueur  · 技术社区  · 15 年前

    我想在特定文件或目录更改时运行shell脚本。

    11 回复  |  直到 7 年前
        1
  •  21
  •   Frédéric Hamidi    15 年前
        2
  •  28
  •   Bruno Bronosky    6 年前

    #!/bin/bash -eu
    DIRECTORY_TO_OBSERVE="js"      # might want to change this
    function block_for_change {
      inotifywait --recursive \
        --event 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 man page

        3
  •  26
  •   kenorb    6 年前

    你可以试试 entr 当文件更改时运行任意命令的工具。文件示例:

    $ ls -d * | entr sh -c 'make && make test'
    

    $ ls *.css *.html | entr reload-browser Firefox
    

    或打印 Changed! 当文件 file.txt

    $ echo file.txt | entr echo Changed!
    

    用于目录 -d ,但您必须在循环中使用它,例如:

    while true; do find path/ | entr -d echo Changed; done
    

    或:

    while true; do ls path/* | entr -pd echo Changed; done
    
        4
  •  4
  •   VDR    12 年前

    这个剧本怎么样?使用“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
    
        5
  •  3
  •   Brian Clements    15 年前
        6
  •  2
  •   Yoric    15 年前

    如前所述,inotify工具可能是最好的主意。但是,如果你是为了好玩而编程,你可以尝试通过明智的应用 tail -f .

        7
  •  1
  •   slowdog    15 年前

    还有一个选择: http://fileschanged.sourceforge.net/

    请特别参阅“示例4”,它“监视目录并存档任何新的或更改的文件”。

        8
  •  1
  •   jonatan Bart    11 年前

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

    "$(ls -lT $file | awk '{ print $8 }')"
    
        9
  •  1
  •   Dan Garthwaite    10 年前

    在~/.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
    }
    
        10
  •  1
  •   pwxcoo    6 年前

    inotifywait 可以满足你。

    下面是一个常见的示例:

    inotifywait -m /path -e create -e moved_to -e close_write | # -m is --monitor, -e is --event
        while read path action file; do
            if [[ "$file" =~ .*rst$ ]]; then             # if suffix is '.rst'
                echo ${path}${file} ': '${action}        # execute your command
                echo 'make html'
                make html
            fi
        done
    
        11
  •  0
  •   Is Ma    6 年前

    使用示例 inotifywait :

    如果我想跑 rails test

    一。列出要查看的相关文件:

    ack 很有助于列这个单子。

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

    2。问 做这项工作

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

    就这样!

    mhallin/vagrant-notify-forwarder 分机。

    更好的是 alias 并删除文件:

    alias rtest="while inotifywait $(ack --type-add=rails:ext:rb,erb --rails -f | tr \\n \ ); do rails test; done"