21

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 6

28

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?

1
  • One caveat to this: dbus may store the session bus address in $HOME/.dbus/session-bus/, but dbus-broker does not. So the first method won't work on any system that's migrated away from the original dbus implementation to dbus-broker. (That list consists of at least: Fedora; most likely RHEL an CentOS as well.) Commented Aug 16, 2021 at 21:07
4

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.

2

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.

1
  • very impressive , actually i'm running KDE4 , so i looked for plasma-desktop instead, thanks ! Commented Jan 7, 2012 at 0:13
1
ps -u yourlogin e | grep -Eo 'dbus-daemon.*address=unix:abstract=/tmp/dbus-[A-Za-z0-9]{10}' | tail -c35
1

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.

1
  • Correction: Dbus doesn't require a session. (How could it require an X session, when so many distros have migrated to Wayland?) dbus-launch requires 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 for DBUS_SESSION_BUS_ADDRESS every time you run it. Commented Sep 14, 2021 at 19:22
0

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:

  1. 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);

  1. in my crontab, start a bash script with the things I want to do, rather than the command itself;

  2. 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.)

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.