Shell – Using notify-send with Cron

cronlibnotifyscriptingshell

I am using Arch Linux with KDE/Awesome WM. I am trying to get
notify-send to work with cron.

I have tried setting DISPLAY/XAUTHORITY variables, and running notify-send with "sudo -u", all without result.

I am able to call notify-send interactively from the session and get notifications.

FWIW, the cron job is running fine which I verified by echoing stuff to a temporary file. It is just the "notify-send" that fails to work.

Code:

[matrix@morpheus ~]$ crontab -l
* * * * *  /home/matrix/scripts/notify.sh

[matrix@morpheus ~]$ cat /home/matrix/scripts/notify.sh
#!/bin/bash
export DISPLAY=127.0.0.1:0.0
export XAUTHORITY=/home/matrix/.Xauthority
echo "testing cron" >/tmp/crontest
sudo -u matrix /usr/bin/notify-send "hello"
echo "now tested notify-send" >>/tmp/crontest

[matrix@morpheus ~]$ cat /tmp/crontest
testing cron
now tested notify-send

[matrix@morpheus ~]$ 

As you can see the echo before & after notify-send worked.
Also I have tried setting DISPLAY=:0.0

UPDATE:
I searched a bit more and found that DBUS_SESSION_BUS_ADDRESS needs to be set. And after hardcoding this using the value I got from my interactive session, the tiny little "hello" message started popping up on the screen every minute!

But the catch is this variable is not permanent per that post, so I'll have try the the named pipe solution suggested there.

[matrix@morpheus ~]$ cat scripts/notify.sh
#!/bin/bash
export DISPLAY=127.0.0.1:0.0
export XAUTHORITY=/home/matrix/.Xauthority
export DBUS_SESSION_BUS_ADDRESS=unix:abstract=/tmp/dbus-BouFPQKgqg,guid=64b483d7678f2196e780849752e67d3c
echo "testing cron" >/tmp/crontest
/usr/bin/notify-send "hello"
echo "now tested notify-send" >>/tmp/crontest

Since cron doesn't seem to support notify-send (at least not directly) is there some other notification system that is more cron friendly that I can use?

Best Answer

You need to set the DBUS_SESSION_BUS_ADDRESS variable. By default cron does not have access to the variable. To remedy this put the following script somewhere and call it when the user logs in, for example using awesome and the run_once function mentioned on the wiki. Any method will do, since it does not harm if the function is called more often than required.

#!/bin/sh

touch $HOME/.dbus/Xdbus
chmod 600 $HOME/.dbus/Xdbus
env | grep DBUS_SESSION_BUS_ADDRESS > $HOME/.dbus/Xdbus
echo 'export DBUS_SESSION_BUS_ADDRESS' >> $HOME/.dbus/Xdbus

exit 0

This creates a file containing the required Dbus evironment variable. Then in the script called by cron you import the variable by sourcing the script:

if [ -r "$HOME/.dbus/Xdbus" ]; then
  . "$HOME/.dbus/Xdbus"
fi

Here is an answer that uses the same mechanism.

Related Question