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

Jan*_*dec 6 cron d-bus

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

它曾经对我有用,在 Debian Stretch(测试)上从切换 systemd 直到最近(可能是一两个月前)。奇怪的是,虽然我强烈怀疑这是由 PAM 配置控制的,但/etc/pam.d最近发生的唯一变化是添加了一些pam_selinuxpam.d/systemd-user.

那么我应该寻找什么?

FeR*_*eRD 10

这可能是因为DBUS_SESSION_BUS_ADDRESS环境变量没有传播到 cron 环境。

在侏儒下至少,公交车不是由“发现”(如记录了的“自动下水”一节中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中没有相应文件的“抽象套接字”。

但是,我们可以使用 ubuntuforum 帖子中提出的想法的变体,通过 SSH 连接到现有 DBUS 会话,从 cron 环境中发现本地计算机上现有用户会话的会话 D-Bus 并进行相应设置$DBUS_SESSION_BUS_ADDRESS

虽然那里使用的技术从诸如nautiluspulseaudio、 和等常用进程中发现环境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
Run Code Online (Sandbox Code Playgroud)

SESSION_MANAGER=lxsession上述适用于LXDE下运行的主桌面会话,侏儒下,你可以设置SESSION_MANAGER=gnome-session和KDE下,你可以使用SESSION_MANAGER=kded4

如果 crontab 中的作业可以访问会话总线,您将在输出中看到类似以下内容:

Fri Dec 18 15:27:02 EST 2015
Success contacting session bus!
Run Code Online (Sandbox Code Playgroud)

否则,您将看到dbus-send.

显然,您可以替代任何其他测试会话总线连接性的方法,包括您实际需要通过 cron 作业执行的任何操作。