python-notify模块与cron: gio.Error
我在寻求一些帮助,想用 python-crontab 来显示通知,因为我尝试过的所有方法都不管用。当脚本通过 cron 启动时,显示没有初始化。但是当我手动启动它时,一切正常。
#!/usr/bin/env python
# coding: utf8
import subprocess
import os
#os.environ.setdefault("XAUTHORITY", "/home/guillaume" + "/.Xauthority")
#os.environ.setdefault('DISPLAY', ':0.0') # do not work
#os.environ['DISPLAY'] = ':0.0' # do not work
print = os.environ
cmd2 = 'notify-send test'
subprocess.call(cmd2, shell=True)
# more code, which is working (using VLC)
cmd3 = "cvlc rtp://232.0.2.183:8200 --sout file/mkv:/path/save/file.mkv" # to download TV's flow
with open("/path/debug_cvlc.log", 'w') as out:
proc = subprocess.Popen(cmd3, stderr=out, shell=True, preexec_fn=os.setsid)
pid = proc.pid # to get the pid
with open("/path/pid.log", "w") as f:
f.write(str(pid)) # to write the pid in a file
# I'm using the pid to stop the download with another cron's task, and to display another notify message.
# Download and stop is working very well, and zenity too. But not notify-send
谢谢
编辑:这是我为这个 cron 脚本设置的环境变量:
{'LANG': 'fr_FR.UTF-8', 'SHELL': '/bin/sh', 'PWD': '/home/guillaume', 'LOGNAME': 'guillaume', 'PATH': '/usr/bin:/bin', 'HOME': '/home/guillaume', 'DISPLAY': ':0.0'}
编辑2:我在 cron 中调用我的脚本是这样的:
45 9 30 6 * export DISPLAY=:0.0 && python /home/path/script.py > /home/path/debug_cron_on.log 2>&1
我想说明一下,我有两个屏幕,所以我认为 DISPLAY:0.0 是显示这个通知的正确方式……但我看不到它。
编辑3:看来我在使用 notify-send 时遇到了问题,因为用 zenity 是可以的:
subprocess.call("zenity --warning --timeout 5 --text='this test is working'", shell=True)
我有 notify-send 版本 0.7.3,并且我想说明 notify-send 在终端中是可以工作的。
编辑4:接下来尝试使用 python-notify。
import pynotify
pynotify.init("Basic")
n = pynotify.Notification("Title", "TEST")
n.show()
日志文件显示这个:(法语)
Traceback (most recent call last):
File "/home/path/script.py", line 22, in <module>
n.show()
gio.Error: Impossible de se connecter : Connexion refusée
#Translating: Unable to connect : Connection refused
所以,我在 dbus 上有问题?这是什么?
解决方案:在创建 cron 任务之前获取 DBUS_SESSION_BUS_ADDRESS:
cron = CronTab()
dbus = os.getenv("DBUS_SESSION_BUS_ADDRESS") # get the dbus
# creating cron
cmd_start = "export DBUS_SESSION_BUS_ADDRESS=" + str(dbus) + " && export DISPLAY=:0.0 && cd /path && python /path/script.py > path/debug_cron.log 2>&1"
job = cron.new(cmd_start)
job = job_start.day.on(self.day_on) # and all the lines to set cron, with hours etc..
cron.write() # write the cron's file
最后,cron 的命令是这样的:
20 15 1 7 * export DBUS_SESSION_BUS_ADDRESS=unix:abstract=/tmp/dbus-M0JCXXbuhC && export DISPLAY=:0.0 && python script.py
然后通知就显示出来了。问题解决了!! :)
2 个回答
0
crontab被认为是一个外部主机——它没有权限写入你的显示屏。
解决方法:允许任何人写入你的显示屏。登录后在你的命令行中输入以下内容:
xhost +
1
你正在这样调用定时任务:
45 9 30 6 * DISPLAY=:0.0 python /home/path/script.py > /home/path/debug_cron_on.log 2>&1
这样是不对的,因为你没有设置DISPLAY
这个变量,后面的命令就不会执行。
试试这个:
45 9 30 6 * export DISPLAY=:0.0 && cd /home/path/ && python script.py >> debug_cron.log 2>&1
另外,你在定时任务中也设置了DISPLAY
变量,所以可以尝试一下不在任务行中导出它,看看定时任务能否正常工作。
45 9 30 6 * cd /home/path/ && python script.py >> debug_cron.log 2>&1
编辑
在调试的时候,可以让定时任务每分钟运行一次。以下这个对我有效:
定时任务条目:
* * * * * cd /home/user/Desktop/test/send-notify && python script.py
script.py
#!/usr/bin/env python
import subprocess
import os
os.environ.setdefault('DISPLAY', ':0.0')
print os.environ
cmd2 = 'notify-send test'
subprocess.call(cmd2, shell=True)
编辑 2
使用pynotify
后,script.py变成:
#!/usr/bin/env python
import pynotify
import os
os.environ.setdefault('DISPLAY', ':0.0')
pynotify.init("Basic")
n = pynotify.Notification("Title", "TEST123")
n.show()
而定时任务条目变成:
* * * * * cd /home/user/Desktop/test/send-notify && python script.py
编辑 3