我了解到有关inotifywait
/inotifywatch
来自 inotify-tools,关于entr
(http://entrproject.org/) 和周围的十几个 shell 脚本,但它们不是我需要的。
我需要的是类似于guard
(https://github.com/guard/guard)。
它的工作方式是:在目录中创建一个文件,指定要监视的内容以及当这些文件发生变化时要做什么。
Guard 还可以,但是 1) 消耗大量资源(而且在大型项目中运行缓慢),2) 需要整个 Ruby + 一堆依赖 gem,3) 需要插件来运行 shell 命令。
还有tup
(http://gittup.org/tup/),它非常棒,除了一个极其愚蠢的限制:它无法输出到除 之外的目录Tupfile
。它的方法是在每个子目录中创建一个Tupfile
,但这对我来说不起作用。
我最终想要的是:我在某个文件中指定文件模式和目录(如果没有,则监视全部),运行某个命令,它会监视与给定规则匹配的内容,每当文件更改/添加时,它都会执行给定的命令。就是这样。
有什么建议么?
答案1
我很快就想到了这一点:
#!/usr/bin/env bash
trap exit SIGQUIT SIGINT
while :; do
watch -n2 -g ls -l /path/to/dir && do_something && do_something_else
done
检查该目录下的每个文件的改变。
简单解释一下:watch -g
当它发现命令输出发生变化时,以状态代码 0 退出。退出时,它会执行与条件 shell 表达式链接的下一个命令(可以是任意多个)。然后,你只需无限循环,直到命中Control-C
(这就是 的用途trap exit SIGQUIT SIGINT
)。
当然,您可能想稍微修改一下这个脚本,例如-n2
更新的时间间隔。更新的次数越多,您花费的资源就越多。
对于单个文件,我建议使用该ls -l --time-format=+%s /path/to/file /path/to/another_file
命令,因为它会检查修改日期甚至权限和所有权的变化。
当然,还有更好、更优化的方法来实现这一点,但这种方法有效,而且消耗的资源肯定比 Guard 少。现在,这一切都取决于可扩展性。如果您要每毫秒递归列出所有文件及其所有属性,这肯定会消耗更多资源,但您绝对不需要这样做。只需设置一个更大的间隔,比如像上面那样设置 2 秒,如果您的项目变化不大,并且您不介意等待一段时间让命令生效,那么可以设置 10 秒或 30 秒。在我看来,这种方法非常好,也很简单。
答案2
看门狗是Python library and shell utilities to monitor filesystem events
。