从 cron 命令访问用户的会话 D-bus

从 cron 命令访问用户的会话 D-bus

需要什么才能让 cron 命令访问会话总线(如果正在运行)?

自从切换 systemd 直到最近(可能是一两个月前),它曾经对我有用,在 Debian Stretch(测试)上。奇怪的是,虽然我强烈怀疑这是由 PAM 配置控制的,但/etc/pam.d最近发生的唯一变化是添加了一些pam_selinuxpam.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-sessionlxsessionkded4)都已$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 作业执行的任何操作。

相关内容