gsettings的奇怪行为使用cron设置了一个新的desktop.background

2024-10-03 06:19:16 发布

您现在位置:Python中文网/ 问答频道 /正文

我想每5分钟更改一次桌面背景。我在ubuntu上,这项工作有效地改变了我的背景:

gsettings set org.gnome.desktop.background picture-uri "file:/img.jpg"

我可以从python脚本启动它,它将从特定目录中选择一个随机图像。我把脚本放在这里,即使我不确定它是否与这里相关

import os
import subprocess as sub
import random
files = [f for f in os.listdir('/usr/share/rwallpaper')]
rando = random.randint(0, (len(files) - 1))
cmd = ["gsettings", "set", "org.gnome.desktop.background", "picture-uri"]
wallpaper = "\"file:/usr/share/rwallpaper/" + files[rando] + "\""
cmd.append(wallpaper)
print(" ".join(cmd)) #to remove after
sub.run(cmd)

这也行得通。所以现在我想使用cron定期执行我的python代码

$ sudo crontab -e
*/5 * * * * python3 /usr/local/cronwal/cronwal.py

但它不起作用。我在某个地方发现这可能是一个用户环境问题,所以我尝试通过以下方式改变上面的执行

*/5 * * * * sudo -u "me" python3 /usr/local/cronwal/cronwal.py
*/5 * * * * su me  -c "python3 /usr/local/cronwal/cronwal.py"

不起作用。要明确的是,在根shell中,原始命令(我文章顶部的第一个gsetting命令)或这两个命令也不起作用,这不是cron问题

因此,我决定使用crontab作为我的用户。也许这是su/sudo无法解决的与用户相关的问题

我试过这个

$crontab -u me -e #in a shell run by "me"
*/5 * * * * python3 /usr/local/cronwal/cronwal.py 

但它不起作用。更确切地说,我可以在cron服务状态中看到

févr. 14 18:05:01 florent-NB50TZ CRON[56843]: pam_unix(cron:session): session opened for user root by (uid=0)
févr. 14 18:05:01 florent-NB50TZ CRON[56844]: pam_unix(cron:session): session opened for user florent by (uid=0)
févr. 14 18:05:01 florent-NB50TZ CRON[56843]: pam_unix(cron:session): session closed for user root
févr. 14 18:05:01 florent-NB50TZ CRON[56849]: (florent) CMD (python3 /usr/local/cronwal/cronwal.py )
févr. 14 18:05:01 florent-NB50TZ CRON[56844]: pam_unix(cron:session): session closed for user florent

(我撒谎,“我”是弗洛伦特)所以

(florent) CMD (python3 /usr/local/cronwal/cronwal.py )

暗示一下,我以florent的身份运行脚本,所以它应该工作相同,对吗? 但是没有。即使脚本与我的florent shell一起运行,cron也不会工作

python3 /usr/local/cronwal/cronwal.py
#change of background

**编辑:**我确实更改了crontab中的行,以便获得反馈。我确实删除了带有选项MAILTO=""的邮件,因此我需要以另一种方式获得反馈

*/5 * * * * python3 /usr/local/cronwal/cronwal.py >> /home/florent/cronwal.log 2>>/home/florent/cronwal.log

正如我所想,没有错误输出。我在日志中只有print(" ".join(cmd))


Tags: py脚本cmdforsessionusrlocalpython3
2条回答

只是一个猜测,但可能gsettings需要您的显示服务器集,只需将您的用户crontab设置为如下所示:

DISPLAY=:0
*/5 * * * * python3 /usr/local/cronwal/cronwal.py

对于错误的调用,您应该在发送给crontab的用户的电子邮件中看到一个错误,如果您配置了本地生成的发送给不合格用户的邮件(请尝试echo . | mail -s testing florent进行测试,但您需要安装类似bsd-mailx的包来进行测试),则可能会告诉您未设置显示。Cron将标准错误和输出发送给运行crontab的用户

所有X程序都需要知道显示服务器,以便在其上执行操作。您可以阅读X(7)手册页了解详细信息。通常,当在X中使用终端时,这个环境变量已经设置好了,但是在crontab中,您需要提供它。如果您使用的不是:0,那么可以在相关X环境中的shell中使用printenv DISPLAY进行检查(顺便说一句:0:0.0相同)

除了$DISPLAY之外,您可能还需要设置$DBUS_SESSION_BUS_ADDRESS环境,因为gsettings正在使用dbus(在未设置DISPLAY时发现,错误消息表示无法自动启动D-Bus);您可以尝试:

DISPLAY=:0
*/5 * * * * eval $(ps -ww -p $(pgrep gnome-session) -o cmd= e | fmt -1 | grep DBUS_SESSION_BUS_ADDRESS) python3 /usr/local/cronwal/cronwal.py

这将从crontab调用程序拥有的gnome-session进程的环境中获取会话地址,并将其设置在python3进程的环境中,从而允许forked gsettings命令通过会话总线进行通信

您可以使用printenv检查终端中是否设置了DBUS_SESSION_BUS_ADDRESS,如果上面有语法错误(我无法测试),则复制该地址,但它将无法在下一个gnome会话上工作。当然,如果您这样硬编码它,则每次都必须更改它:

DISPLAY=:0
*/5 * * * * DBUS_SESSION_BUS_ADDRESS="whatever printenv says" python3 /usr/local/cronwal/cronwal.py

相关问题 更多 >