1

我想每 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"

不起作用。需要明确的是,在 root 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))在日志中。

4

2 回答 2

1

只是一个猜测,但可能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 中你需要提供它。如果您使用的不是,则可以在相关 X 环境中的 shell 中:0检查它(顺便说一句,与 相同)。printenv DISPLAY:0:0.0

于 2021-02-14T17:53:38.660 回答
1

另外$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 进程的环境中,从而允许分叉的gsettings命令通过会话总线进行通信。

您可以检查是否在您的终端中设置了 DBUS_SESSION_BUS_ADDRESSprintenv并复制它,如果上面有一些语法错误(我无法测试),但如果您这样硬编码它,它当然不会在下一个 gnome 会话中工作,您d 每次都必须更改它:

DISPLAY=:0
*/5 * * * * DBUS_SESSION_BUS_ADDRESS="whatever printenv says" python3 /usr/local/cronwal/cronwal.py
于 2021-02-14T23:26:16.080 回答