I need to run some program within crontab , but how can the program know about dbus session id ? it's only available for programs launched by session managers.
6 Answers
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 for DBUS_SESSION_BUS_ADDRESS and DBUS_SESSION_BUS_PID.
dbus_session_file=~/.dbus/session-bus/$(cat /var/lib/dbus/machine-id)-0
if [ -e "$dbus_session_file" ]; then
. "$dbus_session_file"
export DBUS_SESSION_BUS_ADDRESS DBUS_SESSION_BUS_PID
dbus-send …
fi
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.
export $(</proc/$pid/environ tr \\0 \\n | grep -E '^DBUS_SESSION_BUS_ADDRESS=')
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?
-
One caveat to this:
dbusmay store the session bus address in$HOME/.dbus/session-bus/, butdbus-brokerdoes not. So the first method won't work on any system that's migrated away from the originaldbusimplementation todbus-broker. (That list consists of at least: Fedora; most likely RHEL an CentOS as well.)FeRD– FeRD2021-08-16 21:07:35 +00:00Commented Aug 16, 2021 at 21:07
I can't comment on Vincenzo's answer, but I find his answer works best for me on KDE4.
I've had to slightly modify the command though. For me it's:
ps -u yourlogin e | grep -Eo 'dbus-daemon.*ADDRESS=unix:abstract=/tmp/dbus-[A-Za-z0-9]{10}' | tail -c35
Notice ADDRESS in capital letters.
I think if you know the pid of the gnome session manager, then you read the environment from /proc filesystem.
GNOME_SESSION_PID=<PID_OF_GNOME_SESSION>
READ_SESSION_COOKIE="$(grep -z DBUS_SESSION_BUS_ADDRESS /proc/$GNOME_SESSION_PID/environ|cut -d= -f2-)"
Use the SESSION id then, with other programs like notify-send or dbus* tools.
Cheers.
-
very impressive , actually i'm running KDE4 , so i looked for
plasma-desktopinstead, thanks !daisy– daisy2012-01-07 00:13:05 +00:00Commented Jan 7, 2012 at 0:13
ps -u yourlogin e | grep -Eo 'dbus-daemon.*address=unix:abstract=/tmp/dbus-[A-Za-z0-9]{10}' | tail -c35
Yes DBus must have a x session. Like earlier answers, 'DBUS_SESSION_BUS_ADDRESS' must have a value before starting . However, you could use 'dbus-launch' to create this value. Following snippet could be put in a script called from crontab.
if test -z "$DBUS_SESSION_BUS_ADDRESS" ; then
eval `dbus-launch --sh-syntax`
fi
echo "D-Bus daemon address is:"
echo "$DBUS_SESSION_BUS_ADDRESS"
# -E to export DBUS_SESSION_BUS_ADDRESS. Crucial to make DBUS work.
sudo -u <user> -E <program>
One setback with this solution is that the session might hang around after you've stopped your software.
-
Correction: Dbus doesn't require a session. (How could it require an X session, when so many distros have migrated to Wayland?)
dbus-launchrequires a session manager, true. There's a separate utility,dbus-run-session, that can be used to run terminal commands in their own session bus. In a crontab that's probably a better choice. Either way, this won't merely "create [the DBUS_SESSION_BUS_ADDRESS] value", it'll create an entirely separate session bus instance. If you notice, you get a different value forDBUS_SESSION_BUS_ADDRESSevery time you run it.FeRD– FeRD2021-09-14 19:22:36 +00:00Commented Sep 14, 2021 at 19:22
I have been using popups in KDE(-Plasma) from cronjobs for ~10 years using kdialog and later notify-send. My problems started when switching from X11 to Wayland. The issue is that DBUS_SESSION_BUS_ADDRESS is not set - if I set it manually (to the value I get from the terminal), everything works. However, I cannot seem to get the value in the crontab.
My current workaround is:
- in my
.bashrc, add a line
echo $DBUS_SESSION_BUS_ADDRESS > ${HOME}/.dbus-address
Since I use the terminal a lot, this will update the file with the current value every time I start a terminal (which I start doing ~1s after logging into KDE/Plasma);
in my crontab, start a bash script with the things I want to do, rather than the command itself;
in that bash script, before running the command that is supposed to create the popup, do
# Need display when run as cron job:
export DISPLAY=":0"
export XDG_RUNTIME_DIR="/var/run/user/`id -u`"
export DBUS_SESSION_BUS_ADDRESS="`cat ${HOME}/.dbus-address`" # Needed for Wayland - create ~/.dbus-address in .bashrc!
(Actually, I am lying above - for years I've used a bash script called notify-me, which includes the three export statements above and then calls notify-send with some default options. The effect is the same.)