如何在 Linux 中当目录内容发生变化时自动运行脚本?

如何在 Linux 中当目录内容发生变化时自动运行脚本?

我希望在将新文件复制到特定目录时自动运行脚本。换句话说,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

进入是我见过的最简单、最易用的文件通知工具。它的使用针对查看文件而不是目录进行了优化,但它也可以解决您的问题。

要检测并处理添加的文件,请将其与其他工具结合使用,例如makeentr不会发送名称或类似内容,它只是运行您告诉它运行的内容。

要检查目录中添加的文件:

## 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 不受影响)。

相关内容