Cron

從他們的 cron 命令訪問使用者的會話 D-bus

  • December 20, 2019

需要什麼才能讓 cron 命令訪問會話匯流排(如果它正在執行)?

自從切換 systemd 直到最近(可能是一兩個月前),它曾經對我有用,在 Debian Stretch(測試)上。奇怪的是,雖然我強烈懷疑這是由 PAM 配置控制的,但最近發生的唯一變化是添加了一些對to 的/etc/pam.d呼叫。pam_selinux``pam.d/systemd-user

那麼我應該尋找什麼?

這可能是因為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 中沒有對應文件的“抽象套接字”。

但是,我們可以使用 ubuntuforum 文章中提出的想法的變體,通過 SSH 附加到現有 DBUS 會話,從 cron 環境中發現本地電腦上現有使用者會話的會話 D-Bus 並進行$DBUS_SESSION_BUS_ADDRESS相應設置。

雖然那裡使用的技術從常用執行的程序中發現環境,如nautiluspulseaudiotrackerd,並要求它們中的一個或多個在活動會話中執行,但我推荐一種更基本的方法。

所有常見的桌面環境會話管理器(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 作業執行的任何操作。

引用自:https://unix.stackexchange.com/questions/250276