Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

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
[matrix@morpheus ~]$ 

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?

share|improve this question
    
This should work as far as I can see. Why don't you add a &>>/tmp/crontest to the notify send line and see if notify-send gives any error messages. –  Graeme Jan 27 at 19:28
    
Out of curiosity, did you try my solution? It seems much simpler and worked perfectly on my Debian. I'm asking just to know if it Debian specific or not –  terdon Jan 27 at 19:40
    
@terdon I tried your solution (just a quick test) and it seems to work on my Debian system. I'd like to know if it's generally applicable since it is indeed simpler. –  Marco Jan 27 at 19:48
    
@Marco I'm on LMDE (essentially Debian testing) and using Cinnamon as DE. Can't tell you if it works beyond those. –  terdon Jan 27 at 19:52
    
@Marco & terdon: Ubuntu guys are able to do so: ubuntuforums.org/showthread.php?t=1727148 –  justsomeone Jan 27 at 19:53

3 Answers 3

up vote 6 down vote accepted

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.

share|improve this answer
1  
Glad to see that I was almost near to the solution. Thanks Marco, that is neat! –  justsomeone Jan 27 at 19:38
    
Great, I reused your answer and added some more detailed instructions here: askubuntu.com/a/537721/34298 –  rubo77 Oct 18 at 7:09
    
Wouldn't this be a security risk? security.stackexchange.com/questions/71019/… –  rubo77 Oct 18 at 7:18
    
@Gilles How could you do this in one line like you mentioned in chat? –  rubo77 Oct 18 at 7:34

You need to set the variables in the crontab itself:

DISPLAY=:0.0
XAUTHORITY=/home/matrix/.Xauthority

# m h  dom mon dow   command 
* * * * *  /usr/bin/notify-send "hello"

No sudo needed, at least not on my system.

share|improve this answer
    
Thanks terdon for your time. This seems to be a simple solution. Unfortunately, this didn't work for me, –  justsomeone Jan 27 at 19:46
    
@justsomeone huh, OK, might depend on the desktop environment then. –  terdon Jan 27 at 19:47
    
I think this has got something to do with distro or Desktop Environment. For Ubuntu users, the straight forward solutions seems to work fine from what I have seen in online forums. –  justsomeone Jan 27 at 19:50
    
@justsomeone I'm on Debian (LMDE) using Cinnamon as DE. Might have something to do with how X is started or with the notifications system used by the DE, dunno. –  terdon Jan 27 at 19:52
    
Confirmed it works on Ubuntu 14.04/14.10. With GNOME and Unity. –  Jordon Bedwell Sep 29 at 19:32

The safest way to get X session related environmental variables is to get them from the environment of a process of the user who is logged on to X. Here is an adapation of the script that I use for exactly the same purpose (although DBUS_SESSION_BUS_ADDRESS doesn't seem to be a problem for me on Debian):

X=Xorg                   # works for the given X command
copy_envs="DISPLAY XAUTHORITY DBUS_SESSION_BUS_ADDRESS"

tty=$(ps h -o tty -C $X | head -1)
[ -z "$tty" ] && exit 1

# calling who with LANG empty ensures a consistent date format
who_line=$(LANG= who -u | grep "^[^ ]\+[ ]\+$tty")

x_user=$(echo $who_line | cut -d ' ' -f 1)  # the user associated with the tty
pid=$(echo $who_line | cut -d ' ' -f 7)     # the user's logon process

for env_name in $copy_envs
do
  # if the variable is not set in the process environment, ensure it does not remain exported here
  unset $env_name

  # use the same line as is in the environ file to export the variable
  export "$(grep -az ^$env_name= /proc/$pid/environ)" >/dev/null
done

sudo -u "$x_user" notify-send "hello"

This sends to message to the first X user it finds, although you could add a loop to send it to all users. Hope this helps.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.