需要什么才能让 cron 命令访问会话总线(如果正在运行)?
自从切换 systemd 直到最近(可能是一两个月前),它曾经对我有用,在 Debian Stretch(测试)上。奇怪的是,虽然我强烈怀疑这是由 PAM 配置控制的,但/etc/pam.d
最近发生的唯一变化是添加了一些pam_selinux
对pam.d/systemd-user
.
那么我应该寻找什么?
答案1
这可能是由于DBUS_SESSION_BUS_ADDRESS
环境变量未传播到 cron 环境。
至少在 Gnome 下,总线不是“可发现的”(如文档的“自动启动”部分所述)dbus-launch(1)
手册页)通过 中的文件$HOME/.dbus/session-bus
。这使得 crontab 中运行的任何内容都无法发现$DBUS_SESSION_BUS_ADDRESS
和联系会话 D-Bus。
我相信你的话,它在过去有效,可能是由于使用$HOME/.dbus
或存在/tmp/dbus-$TMPNAM
引用的实际文件$DBUS_SESSION_BUS_ADDRESS
(通常设置为类似于unix:abstract=/tmp/dbus-GkJdpPD4sk,guid=0001e69e075e5e2
)。正如dbus-cleanup-sockets(1)
手册页所解释的:
在Linux上,这个程序本质上是无用的,因为D-Bus默认使用仅存在于内存中的“抽象套接字”,并且在/tmp中没有相应的文件。
然而,我们可以使用 ubuntu 论坛帖子中提出的想法的变体,通过 SSH 连接到现有的 DBUS 会话,从 cron 环境中发现本地计算机上现有用户会话的会话 D-Bus 并进行$DBUS_SESSION_BUS_ADDRESS
相应设置。
nautilus
虽然那里使用的技术从常见运行的进程(如、pulseaudio
和)中发现环境,trackerd
并要求其中一个或多个进程在活动会话中运行,但我建议采用一种更基本的方法。
所有常见的桌面环境会话管理器(gnome-session
、lxsession
和kded4
)都已$DBUS_SESSION_BUS_ADDRESS
在其环境中进行设置,即使它们之前已启动dbus-daemon
并且具有较低的 PID。因此,使用与您的桌面环境相对应的任何会话管理器是最有意义的。
我编写了以下脚本,放置在 中$HOME/bin/test-crontab-dbus.sh
,以测试对现有会话总线的访问:
#!/bin/sh
SESSION_MANAGER=lxsession
OUTFILE=/tmp/${USER}-cron-dbus.txt
export $(cat /proc/$(pgrep "$SESSION_MANAGER" -u "$USER")/environ \
|egrep -z '^DBUS_SESSION_BUS_ADDRESS=')
date >> $OUTFILE
dbus-send --session --dest=org.freedesktop.DBus \
/ org.freedesktop.DBus.GetId 2>> $OUTFILE
if test "$?" -eq 0; then
echo "Success contacting session bus!" >> $OUTFILE
fi
上述SESSION_MANAGER=lxsession
内容适用于在 LXDE 下运行的主桌面会话、在您设置的 Gnome 下SESSION_MANAGER=gnome-session
以及在您使用的 KDE 下运行SESSION_MANAGER=kded4
。
如果 crontab 中的作业可以访问会话总线,您将在输出中看到类似以下内容:
Fri Dec 18 15:27:02 EST 2015
Success contacting session bus!
否则,您将看到 输出的错误消息dbus-send
。
显然,您可以替代任何其他测试会话总线连接的方法,包括您实际需要通过 cron 作业执行的任何操作。