我有一个用户 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) 是绝对路径。