我希望在将新文件复制到特定目录时自动运行脚本。换句话说,Linux 中是否有办法“监视”目录的更改,然后运行某些脚本来响应更改?
答案1
如果您足够幸运,使用的是基于 Debian 的发行版apt-get install dnotify
。其他发行版可能也有类似的东西 - 查找dnotify
名称。
dnotify 是一个基于 Linux 内核 2.4.19+ 的 dnotify API 的简单程序。dnotify 可以在特定目录的内容每次发生变化时执行指定的命令。它从命令行运行并接受两个参数:要监视的一个或多个目录以及目录发生变化时要执行的命令。选项控制触发哪些事件:在目录中读取文件时、创建文件时、删除文件时等等。
如果您想在自己的程序中处理这个问题,dnotify 也是您想要使用的 API。
答案2
您可以使用 inotify-tools 运行脚本,如下所示。它将监视目录中已修改文件、新文件和已删除文件的变化,然后执行该脚本。
#!/bin/sh
while inotifywait -e modify -e create -e delete /home/me/code; do
rsync [options] /home/me/code/ /media/nfs/code/
done
答案3
因克龙我认为基本上就是您想要的。它使用 inotify 作为通知机制(正如其他人指出的那样,它取代了 dnotify),但不需要使用 inotifywait 或类似程序连续运行的脚本(尽管显然 incron 守护进程一直在运行)。系统范围的“crontabs”和用户“crontabs”的支持方式与标准 cron 类似,但不是指定时间作为触发器,而是使用 inotify 事件和文件/目录名称。
我相信,incron 适用于许多发行版,包括 Ubuntu 和 Debian。
答案4
进入是我见过的最简单、最易用的文件通知工具。它的使用针对查看文件而不是目录进行了优化,但它也可以解决您的问题。
要检测并处理添加的文件,请将其与其他工具结合使用,例如make
。entr
不会发送名称或类似内容,它只是运行您告诉它运行的内容。
要检查目录中添加的文件:
## entr exits with rc=0 when terminated
## rc=1 when watched files go away or don't exist to begin with
## rc=2 when new files arrive in watched directories
until echo /path/to/directory_to_watch | entr -d do_stuff
do sleep 1; done
如果您还想在现有文件发生更改时采取行动:
## Here's why it comes in handy that entr exits when new files are added --
## find gets re-run.
until find /path/to/directory_to_watch/ -path /path/to/directory_to_watch/* |
entr -d do_stuff
do sleep 1; done
...这就是循环机制派上用场的地方,因为find
如果添加文件,表达式将再次运行。
如果您想要更好的错误处理,并确保每个添加/删除的文件只运行一次,事情就会变得有点古怪,但对于这些简单的情况来说,它非常棒。
编辑:如果你想在系统层面上做到这一点,比如因克龙,只需将脚本添加到你最喜欢的进程管理器(例如s6,运行,systemd或者系统初始化并跳过循环:
#!/bin/bash
exec entr -d do_stuff < <(find /path/to/directory_to_watch/ -path /path/to/directory_to_watch/*)
当从进程管理器运行时,进程exec
替换(<(...)
)非常重要,以便正确处理信号(即让 shell 不受影响)。