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 '14 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 '14 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 '14 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 '14 at 19:52
    
@Marco & terdon: Ubuntu guys are able to do so: ubuntuforums.org/showthread.php?t=1727148 –  justsomeone Jan 27 '14 at 19:53

5 Answers 5

up vote 10 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 '14 at 19:38
    
Great, I reused your answer and added some more detailed instructions here: askubuntu.com/a/537721/34298 –  rubo77 Oct 18 '14 at 7:09
    
Wouldn't this be a security risk? security.stackexchange.com/questions/71019/… –  rubo77 Oct 18 '14 at 7:18
    
@Gilles How could you do this in one line like you mentioned in chat? –  rubo77 Oct 18 '14 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 '14 at 19:46
    
@justsomeone huh, OK, might depend on the desktop environment then. –  terdon Jan 27 '14 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 '14 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 '14 at 19:52
    
Confirmed it works on Ubuntu 14.04/14.10. With GNOME and Unity. –  Jordon Bedwell Sep 29 '14 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

Here is a less complex script than what Graeme provided. His script didn't work for me, $who_line was always empty. My script doesn't waste so much time with finding a process. Instead, it just tries all and pick the last useful value found. I'm running xubuntu 14.04 and have some lxc containers running which probably confuse this kind of scripts.

env="$(
  ps -C init -o uid,pid | while read u p; do
    [ "$u" = "`id -u`" ] || continue
    grep -az '^DBUS_SESSION_BUS_ADDRESS=' /proc/$p/environ | xargs -0
  done | tail -1
)"

export "$env"

notify-send "test"
share|improve this answer

I use this script in cron to post MPD now playing to twitter every hour

#!/bin/bash
export DISPLAY=":0.0"
msg=$(mpc current -h 192.168.1.33)
twitter set "#MPD Server nowplaying $msg :  http://cirrus.turtil.net:9001"
#ttytter -status="#MPD Server nowplaying $msg. http://cirrus.turtil.net:9001"

exit 

similar script using notify-send

#!/bin/bash
export DISPLAY=":0.0"
notify-send -i ~/.icons/48arch.png 'OS- Archlinux x86_64 : DWM Window Manager' 'Installed on Sun Apr 21 2013 at 18:17:22' 
exit

you may be experiencing problems as KDE uses its own notify-deamon IIRC.

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.