有没有办法在文件上设置类似触发器的东西,以便每次更改文件时都会执行脚本或程序?
我只在 shell 脚本中找到了这种机制,但我想知道是否有基于操作系统的机制(这样我就不必手动运行后台程序)。基于操作系统的解决方案是每隔几秒运行一次 cron-job,但在我看来这不是一个合适的解决方案。
顺便说一下,它适用于 Debian。
感谢帮助。
答案1
您的选择之一是通知Linux内核的子系统:
inotify 是一个 Linux 内核子系统,用于扩展文件系统,以通知文件系统的变化,并将这些变化报告给应用程序
但是因为inotify
它是内核空间的,所以你需要用户空间中的一些东西才能真正使用它:
- 英克罗恩:
inotify cron 守护进程 (incrond) 是一个用于监视文件系统事件并执行系统和用户表中定义的命令的守护进程。它的使用与 cron(8) 大致相同。
- 野孩子:
Gamin 是一个文件和目录监控系统,它独立实现了 FAM(文件更改监控器)的一个子集。它以服务形式运行,可以检测对文件或目录的修改。gam_server 充当 Gamin 的守护进程。
- ‘信息传递':
inoticoming - 当文件到达传入目录时触发操作
askubuntu 上有一个类似问题的答案:
答案2
另一种快速而简单的方法是使用inotifywait
inotify-tools 包(在 fedora 上)。
我更喜欢这种方法,因为您可以通过单个 bash 命令行完成所有操作。我在编写小程序时经常使用这种方法来查看刚刚保存的结果。
while [[ 1 ]]; do inotifywait -e modify <filename>; make && ./helloworld; done
答案3
我认为shell 脚本中的一种机制是一个完美的解决方案,并且基于操作系统的机制(这样我就不必手动运行后台程序)只是意味着把解决方案放入流程管理器中s6,运行, A系统单元,甚至inittab 条目如果您使用的是 sysvinit 系统。
无论保持其运行的机制是什么,我喜欢进入用于查看文件。简单、切中要点、可组合(例如,将其放入进程管理器中很简单)。
/path/to/file
这是一个用于观察并在发生变化时运行的脚本/usr/local/bin/do_stuff
:
#!/bin/bash
exec entr /usr/local/bin/do_stuff < <(echo /path/to/file)
这就是全部内容。将其放入run
runit 或 s6 文件中,将其放入ExecStart
systemd 单元行中,或从 中的行调用该脚本inittab
。尽管如果您将其放入,inittab
您可能希望sleep
在某处添加,因为 sysvinit 不会对由于拼写错误、文件丢失等原因立即失败的进程进行速率限制。
为什么不只是echo /path/to/file | entr /usr/local/bin/do_stuff
?在进程管理下运行时,被管理的进程必须直接受监管,这样它在关机等情况下才能正常运行。如果 shell 在监管下运行,shell 将捕获任何TERM
、INT
或KILL
信号,而不是它正在运行的进程,并且不会传递它们。或者,它将退出并使进程成为孤立进程。exec
从进程链中移除 shell。(exec
在 的右侧|
没有区别)
或者只是使用一个永远不会把自己置于中间的外壳,执行程序:
#!/bin/execlineb
pipeline -d {
echo /path/to/file
} entr /usr/local/bin/do_stuff