在 Debian 中的 incrontab 中运行 python 脚本

在 Debian 中的 incrontab 中运行 python 脚本

我有一个用户 dropbox,它运行 Dropbox 守护程序,我想监视 Dropbox 目录中的新文件,并在它们出现时运行 python 脚本。

我有我知道可以工作的python脚本:

$ /home/dropbox/monitor.py
Trying to get lock
Got lock, waiting for Dropbox to be idle
Dropbox idle
Finding instructions
Done, releasing lock

我有一个 incrontab 条目:

$ incrontab -l
/home/dropbox/Dropbox IN_CREATE /home/dropbox/monitor.py | logger
/home/dropbox/test IN_CREATE logger "$$ $@ $# $% $&"

当我将文件添加到测试目录时,我看到输出/var/log/syslog

$ touch /home/dropbox/test/a
$ tail /var/log/syslog
...
Nov  9 10:18:27 vps incrond[1354]: (dropbox) CMD (logger "$ /home/dropbox/test a IN_CREATE 256")
Nov  9 10:18:27 vps logger: "$ /home/dropbox/test a IN_CREATE 256"
...

但是,当我将文件添加到 Dropbox 目录时,命令似乎没有运行:

$ touch /home/dropbox/Dropbox/a
$ tail /var/log/syslog
...
Nov  9 10:24:16 vps incrond[1354]: (dropbox) CMD (/home/dropbox/monitor.py | logger)
...

因此,incron 守护程序注意到了新文件,并发现执行了正确的命令,但实际上从未执行过。也没有任何错误消息。似乎 incrontab 只能用于运行最简单的命令。

这可能是一个类似的问题:

但我认为我没有环境问题,每个路径都是绝对路径。我尝试更改.../monitor.py/usr/bin/python2.7 .../monitor.py以防万一,但没有任何区别。

编辑

Dennis Kaarsemaker 提出了一个解决方案,即 incrontab 以非 cron 方式执行我的命令,这可能是导致问题的原因。不幸的是,我仍然无法让它工作。

首先我从 incrontab 中删除了多余的内容:

$ incrontab -l
/home/dropbox/Dropbox IN_CREATE /home/dropbox/monitor.py

这应该只运行我的监控文件,而不会尝试将任何东西作为参数传入。没有成功,仍然没有输出。

然后我创建了一个 bash 脚本,其中包含我的脚本的执行指令:

$ vim test.sh
logger "$PATH"
/usr/bin/python2.7 /home/dropbox/monitor.py | logger

这将产生以下输出:

$ tail /var/log/syslog
Nov  9 23:50:28 vps incrond[1354]: (dropbox) CMD (/home/dropbox/test.sh)
Nov  9 23:50:28 vps logger: /usr/local/bin:/usr/bin:/bin:/usr/X11R6/bin

因此,从 monitor.py 中我们可以看到任何内容,包含 python 的目录位于 incrontab 的环境中,所以我们甚至不需要像我们那样绝对地指定路径。

答案1

cron 和 incron 之间有很大区别:它们执行命令的方式不同。Cron 将命令视为一个参数,并调用 shell 来运行它。大致如下:

execvp('/bin/sh', ['/bin/sh', '-c', 'whatever is in the crontab']);

因此,所有 shell 构造都像&&和一样|有效。Incron 不会这样做,它会解析命令本身并直接执行它。因此,在您的情况下,incron 运行的是:

execvp('/home/dropbox/monitor.py', ['/home/dropbox/monitor.py', '|', 'logger']);

因此,您的 monitor.py 将使用|logger作为参数运行。您可以将脚本包装在另一个脚本中,monitor.py | logger也可以使用 pythonlogging模块从 monitor.py 本身进行日志记录。

答案2

我感觉自己像个白痴一样注意到了这一点。

我的 monitor.py 脚本在开始处理 dropbox 内容之前尝试获取文件锁定。这主要是为了阻止其他 monitor.py 实例干扰。我锁定的文件路径不是绝对的。

所以,以后任何人看到这个页面都会得到教训。检查你使用的每条路径,确保它 1) 在路径上 2) 是绝对路径。

相关内容