Indeed when an SSH session is open, it doesn't launch a dbus session. Some programs may launch it, but then the session doesn't know about it (hence can't close it).
Not knowing about the dbus session also means that programs that use dbus but don't launch it themselves will have problems.
dbus sections are per machine and per X11 display.
Their info is stored in $HOME/.dbus/session-bus/-
however, the process referenced there may be closed, so an extra check is needed to determine if launching dbus is needed or not.
Then, the variables there are to be exported to the session.
Then it works like a charm :)
I put the following in my .bash_profile file:
# set dbus for remote SSH connections
if [ -n "$SSH_CLIENT" -a -n "$DISPLAY" ]; then
machine_id=$(LANGUAGE=C hostnamectl|grep 'Machine ID:'| sed 's/^.*: //')
x_display=$(echo $DISPLAY|sed 's/^.*:\([0-9]\+\)\(\.[0-9]\+\)*$/\1/')
dbus_session_file="$HOME/.dbus/session-bus/${machine_id}-${x_display}"
if [ -r "$dbus_session_file" ]; then
export $(grep '^DBUS.*=' "$dbus_session_file")
# check if PID still running, if not launch dbus
ps $DBUS_SESSION_BUS_PID | tail -1 | grep dbus-daemon >& /dev/null
[ "$?" != "0" ] && export $(dbus-launch) >& /dev/null
else
export $(dbus-launch) >& /dev/null
fi
fi
notes: hostnamectl is part of systemd and allows to retrieve the machine-id
the dbus-launch displays the variables we want; by using export $(dbus-launch)
we retrieve the output of dbus-launch and export the variables
Best Answer
The problem is somewhat similar to accessing the X display and finding the location of the X cookie file. (Also, refer to these questions if you want to launch a GUI program on the user's display.)
Dbus stores the session address in a file in
~/.dbus/session-bus
. The name of the file is$machine_id-$display_number
, where$machine_id
is a randomly generated number stored in/var/lib/dbus/machine-id
and$display_number
is the X display number ($DISPLAY
is:$display_number
or:$display_number.$screen_number
). The file in~/.dbus/session-bus
is parseable by a shell and contains definitions forDBUS_SESSION_BUS_ADDRESS
andDBUS_SESSION_BUS_PID
.Beware that there's no guarantee that the dbus daemon is still available. The user may have logged out.
An alternative method is to find the PID of a process in the desktop session, and obtain the dbus address from its environment.
If the crontab is running as root and you want to communicate with the session of whatever user is logged in on the console, see Can I launch a graphical program on another user's desktop as root?