Take the 2-minute tour ×
Ask Ubuntu is a question and answer site for Ubuntu users and developers. It's 100% free, no registration required.

I made a script that should notify me when there's a new chapter of manga that I'm reading. I used the command notify-send to do this. The program works when I am trying to run it in terminal. The notification is showing. However, when I placed this in my crontab, the notification doesn't show. I'm pretty sure that the program is running since I made it to create a file for me. The file was created, but the notification didn't show.

Here's my script

#!/bin/bash

#One Piece Manga reminder

#I created a file named .newop that contains the latest chapter.

let new=$(cat ~/.newop)

wget --read-timeout=30 -t20 -O .opreminder.txt http://www.mangareader.net/103/one-piece.html

if (( $(cat .opreminder.txt | grep "One Piece $new" | wc -l) >=1 ))

then

    (( new+=1 ))

    echo $new

    echo $new > ~/.newop

    notify-send "A new chapter of One Piece was released."

else

    notify-send "No new chapter for One Piece."

    notify-send "The latest chapter is still $new."

fi    

exit

And here's what I wrote in my crontab

0,15,30,45 12-23 * * 3   /home/jchester/bin/opreminder.sh
share|improve this question
    
Just a reminder, all commands in crontab need to have their path in front of them as they run as root. Attaching script and line in crontab would help otherwise we are just guessing at your problem –  Meer Borg May 22 '13 at 11:44
    
Yeah, sorry. I just did. –  user158335 May 22 '13 at 12:01
    
This is a bad idea. Notifications are a "GUI" thing, cron is a "console" thing. There is no gaurentee that lib-notify will be able to find a way to display the message. Instead you should consider sending data to stdout and let cron's messaging take care of sending the info. Normally an email is sent. –  coteyr May 22 '13 at 12:53
1  
In some cases setting the DISPLAY variable up may help as well, e.g.: export DISPLAY=:0. –  Glutanimate May 22 '13 at 14:50

5 Answers 5

up vote 7 down vote accepted

Commands need to reference their location. So notify-send needs to be /usr/bin/notify-send

All commands need to have their full path.

Use the whereis notify-send command to see where your commands "live"

share|improve this answer
    
Does that include cat, wget, if, let, grep, echo, etc? –  user158335 May 22 '13 at 12:10
    
If the whereis command returns a value yes, "if/echo/exit" is the exception as its internal to bash, you will note "whereis id" returns "if:" denoting internal command –  Meer Borg May 22 '13 at 12:12
    
Nice! Thank you very much Meer! –  user158335 May 22 '13 at 12:16
    
enable -a will show you the internal commands. –  l0b0 May 22 '13 at 14:25
    
At least on my system, notify-send is on the PATH even for a cron job. See my answer below. –  krlmlr Sep 17 '13 at 9:11

Command notify-send would not show the message on your screen when started by cron. Just add target display at the top of your script:

export DISPLAY=:0

Works for me with Ubuntu 14.04.

share|improve this answer
    
This is what I had to do in 14.10 too. Otherwise I would get this error gdk_mir_display_open Failed to connect to Mir: Failed to connect to server socket: No such file or directory Option parsing failed: Cannot open display: –  Joelmob Oct 29 at 23:43

Things seem to be different on 13.04, at least in Gnome Shell.

First, this is what env prints when run from user zzyxy's (not root's) cron job:

HOME=/home/zzyxy
LOGNAME=zzyxy
PATH=/usr/bin:/bin
XDG_RUNTIME_DIR=/run/user/zzyxy
LANG=en_US.UTF-8
SHELL=/bin/sh
PWD=/home/zzyxy

To get notify-send to work, it seems to be necessary to set the DBUS_SESSION_BUS_ADDRESS environment variable, as per DahitiF's comment on ubuntuforums.org. Just prepend the following to your actual job description:

eval "export $(egrep -z DBUS_SESSION_BUS_ADDRESS /proc/$(pgrep -u $LOGNAME gnome-session)/environ)";

It doesn't seem to be necessary to set DISPLAY.

share|improve this answer

First culprit is your crontab file, you also need to mention the user name with which the script has to be executed, better keep it as root

0,15,30,45 12-23 * * 3 root   /home/jchester/bin/opreminder.sh

and then you should use the user_name of the GUI user inside the script and prepend it to notify-send with "sudo or su" to execute the command as a user who owns the GUI

example :

su gnome_user_name -c 'notify-send "summary" "body"'

or

sudo -u gnome_user_name notify-send "summary" "body"

where gnome_user_name is the username of the user who started the GUI session it is you who logged in, and if you want to make it a dynamic pick, you can get it from

GNOME_USER=`ps -ef | grep gnome-session | grep -v grep | head -1 | cut -d ' ' -f1`

example :

su $GNOME_USER -c 'notify-send "summary" "body"'

or

sudo -u $GNOME_USER notify-send "summary" "body"
share|improve this answer

For Ubuntu 14.04 at least, klrmr's response above is the correct answer. It does not appear to be necessary to set DISPLAY or articulate full paths for notify-send or anything otherwise normally in $PATH.

Below is a cron script I'm using to shutdown a virtual machine when a laptop's battery state becomes too low. The line setting DBUS_SESSION_BUS_ADDRESS in klrmr's response above is the modification that finally got the warnings working correctly.

#!/bin/bash

# if virtual machine is running, monitor power consumption
if pgrep -x vmware-vmx; then
  bat_path="/sys/class/power_supply/BAT0/"
  if [ -e "$bat_path" ]; then
    bat_status=$(cat $bat_path/status)
    if [ "$bat_status" == "Discharging" ]; then
      bat_current=$(cat $bat_path/capacity)
      # halt vm if critical; notify if low
      if [ "$bat_current" -lt 10 ]; then
        /path/to/vm/shutdown/script
        echo "$( date +%Y.%m.%d_%T )" >> "/home/user/Desktop/VM Halt Low Battery"
        elif [ "$bat_current" -lt 15 ]; then
            eval "export $(egrep -z DBUS_SESSION_BUS_ADDRESS /proc/$(pgrep -u $LOGNAME gnome-session)/environ)";
            notify-send -i "/usr/share/icons/ubuntu-mono-light/status/24/battery-caution.svg"  "Virtual machine will halt when battery falls below 10% charge."
      fi
    fi
  fi
fi

exit 0
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.