Bash脚本,监视文件夹,执行命令

Tho*_*ggi 37 macos bash shell

我正在尝试创建一个带有2个参数的bash脚本:目录和命令.我需要查看此目录以进行更改,并且当某些内容发生更改时,我需要执行该命令.我真的很喜欢用bash编写脚本而且我不确定我在做什么,所以对我很轻松.我也在Mac上,而不是linux.任何指针或外部资源都会有很大帮助.我知道有很多人在互联网上尝试这一点,似乎没有人能够做到这一点.我真的想模仿SASS的手表功能.

#!/bin/bash

#./watch.sh $PATH $COMMAND

DIR=$1  

ls -l $DIR > $DIR/.begin
#this does not work
DIFFERENCE=$(diff .begin .end)

if [ $DIFFERENCE = '\n']; then
    #files are same
else
    $2
fi 

ls -l $DIR > $DIR/.end
Run Code Online (Sandbox Code Playgroud)

Rad*_*dek 38

要连续递归监视文件夹(md5)并在更改时执行命令:

daemon() {
    chsum1=""

    while [[ true ]]
    do
        chsum2=`find src/ -type f -exec md5 {} \;`
        if [[ $chsum1 != $chsum2 ]] ; then           
            compile
            chsum1=$chsum2
        fi
        sleep 2
    done
}
Run Code Online (Sandbox Code Playgroud)

在我的操作系统X上工作,因为我没有digest.

在Linux上,您可以md5sum用作md5命令的替代品.

  • @oshyshko你可以修改https://github.com/alandipert/fswatch的URL吗? (6认同)
  • 不错,我建议用`chsum1 = $ chsum2`替换`chsum1 = ...`.否则,不会注意到`compile`期间发生的变化. (4认同)
  • OS X有"fswatch",这里:https://github.com/alandipert/fswatchIt这是一个使用FSEvents API的小命令,所以它做同样的事情,但节省你的CPU.对大型项目来说更好(不需要MD5一切). (3认同)
  • +1.小小的评论,`find src/-type f -mtime -5s`明显更快,并且几乎不需要cpu,因为它不会对每个文件执行.它检查是否有任何改变超过5秒. (3认同)

Swi*_*ift 10

方法1:

#!/bin/sh

check() {
    dir="$1"
    chsum1=`digest -a md5 $dir | awk '{print $1}'`
    chsum2=$chsum1

    while [ $chsum1 -eq $chsum2 ]
    do
        sleep 10
        chsum2=`digest -a md5 $dir | awk '{print $1}'`
    done

    eval $2
}

check $*
Run Code Online (Sandbox Code Playgroud)

该脚本包含两个参数[directory,command].脚本每10秒执行一次check()以查看文件夹已更改.如果没有,它会睡觉并且循环重复.

如果文件夹已更改,eval则为您的命令.

方法2:
使用cron监视文件夹.

你必须安装incron:

 sudo apt-get install incron
Run Code Online (Sandbox Code Playgroud)

然后你的脚本看起来像这样:

#!/bin/bash
eval $1
Run Code Online (Sandbox Code Playgroud)

(您不需要指定文件夹,因为它将是cron的工作来监视指定的目录)

这里有一个完整的工作示例:

http://www.errr-online.com/index.php/2011/02/25/monitor-a-directory-or-file-for-changes-on-linux-using-inotify/

  • 你可以使用`md5sum`(或者更可靠的是,`sha1sum`). (3认同)

Evi*_*ine 10

我不敢相信没人发布这个.

首先确保inotify-tools已安装.

然后像这样使用它们:

logOfChanges="/tmp/changes.log.csv" # Set your file name here.

# Lock and load
inotifywait -mrcq $DIR > "$logOfChanges" &
IN_PID=$$

# Do your stuff here
...

# Kill and analyze
kill $IN_PID
cat "$logOfChanges" | while read entry; do
   # Split your CSV, but beware that file names may contain spaces too.
   # Just look up how to parse CSV with bash. :)
   path=... 
   event=...
   ...  # Other stuff like time stamps?
   # Depending on the event…
   case "$event" in
     SOME_EVENT) myHandlingCode path ;;
     ...
     *) myDefaultHandlingCode path ;;
done
Run Code Online (Sandbox Code Playgroud)

或者,使用--format而不是-con inotifywait将是一个想法.

只是man inotifywaitman inotifywatch更多的相关信息.

  • 我注意到`inotify-tools`需要一个支持`inotify`的Linux内核.除非你对Mac OS X和"inotify"有所了解,否则没有其他人能做到这一点,因此没有直接的"inotify"支持(但是`FSEvents` API - 文件系统事件 - 将接近所需的功能,即使界面不同). (3认同)
  • 刚刚尝试在 Mac 上安装 `inotify-tools` 并失败,如果您感兴趣,请发布 [github 问题](https://github.com/rvoicilas/inotify-tools/issues/11)。 (2认同)
  • @JonathanLeffler:使用`FSEvents`的`fswatch`似乎是一个不错的全功能选择:http://stackoverflow.com/questions/1515730/is-there-a-command-like-watch-or-inotifywait -on-the-mac (2认同)

Tho*_*ggi 9

这是一个观察文件夹进行更改并在更新文件时运行less编译器的示例.作为先决条件,你需要npm和这些模块onchange.节点社区有一大堆不同的监视命令(比如onchange)我不知道任何编译自包含的二进制文件.

npm install less onchange -g
Run Code Online (Sandbox Code Playgroud)

然后你可以使用类似的东西:

onchange "./stylesheets/*.less" -- lessc main.less > main.css
Run Code Online (Sandbox Code Playgroud)

我更喜欢BASH命令而不是Grunt的答案.


Dev*_*rim 5

可能是最快的方式..(在1G git repo上,在1秒内返回.)

#!/bin/bash

watch() {

    echo watching folder $1/ every $2 secs.

while [[ true ]]
do
    files=`find $1 -type f -mtime -$2s`
    if [[ $files == "" ]] ; then
        echo "nothing changed"
    else
            echo changed, $files
    fi
    sleep $2
done
}

watch folder 3
Run Code Online (Sandbox Code Playgroud)

  • 小心,`watch`是许多系统上的内置命令. (4认同)
  • 这是非常简短和巧妙的,因为您不必安装额外的依赖项。但它没有捕获的一件事是删除;仅添加/更新。 (3认同)