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

#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 ))    
    (( new+=1 ))    
    echo $new    
    echo $new > ~/.newop    
    notify-send "A new chapter of One Piece was released."    
    notify-send "No new chapter for One Piece."    
    notify-send "The latest chapter is still $new."    

And here's what I wrote in my crontab

0,15,30,45 12-23 * * 3   /home/jchester/bin/opreminder.sh
  • 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
  • For 16.04, this one worked for me */1 * * * * eval "export $(egrep -z DBUS_SESSION_BUS_ADDRESS /proc/$(pgrep -u $LOGNAME gnome-session)/environ)";/usr/bin/notify-send -i appointment -c "im" "Keep Working" – KrIsHnA Jul 8 '18 at 5:57

13 Answers 13


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"

  • 2
    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
  • 4
    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

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:


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.

  • 2
    Thanks, this is what finally worked for me. On Xubuntu, you have to change gnome-session to xfce4-session. – shrx Feb 19 '15 at 10:05
  • This is the only answer to work for 14.04, along with the obvious hint of the accepted one. – Wtower Feb 28 '15 at 11:34
  • 1
    I had no gnome-session and used gnome-shell instead (be careful there is also a gnome-shell-calendar-server so pgrep will get 2 pids). I also needed DISPLAY=:0 because I'm using 2 phisical screens and it was not defined. Thanks! – soyuka May 27 '15 at 15:05
  • If you're using Openbox (like on CB++) swap in openbox for gnome-session. – ACK_stoverflow Oct 3 '16 at 19:06

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, for example:

export DISPLAY=:0
  • 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 '14 at 23:43
  • 1
    This. And use echo $DISPLAY in a terminal to make sure your display really is :0 (it usually is, but not always). – Mark Feb 7 '16 at 16:16
  • Only this worked for me, I am using Linux Mint – Harendra Singh Apr 6 '16 at 8:32

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.


# if virtual machine is running, monitor power consumption
if pgrep -x vmware-vmx; then
  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
        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."

exit 0

In my case with ubuntu 16.04 any explicit path was required, I solve the problem just adding


at firsts lines of the crontab, before call notify-send.

  • This is the only thing necessary to get it to work on 16.04. – Jonathan Landrum Apr 3 '18 at 21:15

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"'


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 -eo uname,cmd | grep gnome-session| head -1 | cut -d' ' -f1 `

example :

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


sudo -u $GNOME_USER notify-send "summary" "body"
  • 1
    I think that when your username is longer than X characters, your usernma is truncated: For example, my username is oniltonmaciel, but $GNOME_USER would show onilton+ (doesn't work) – Onilton Maciel Apr 25 '15 at 21:03
  • fixed it with better command – Sundeep Borra Apr 27 '15 at 9:01

The way the binary retrieves the dbus address seems to have changed lately. On Ubuntu 15.04 (Vivid Vervet) with "notify-send 0.7.6", the following two variables are needed:

export HOME=/home/$notify_user
export DISPLAY=:0.0

The statement by 'krlmlr' evaluates fine and sets the correct address, but the dialog won't pop up from a cron job.


If your script in crontab is running as root, the answers above will probably not work. Try this function, which works fine for me in 16.04 :

notify_all() {
    local title=$1
    local msg=$2

    who | awk '{print $1, $NF}' | tr -d "()" |
    while read u d; do
        id=$(id -u $u)
        . /run/user/$id/dbus-session
        export DISPLAY=$d
        su $u -c "/usr/bin/notify-send '$title' '$msg'"

( Source: https://unix.stackexchange.com/a/344377/7286 )


Better to rely on dbus-session process, it should be running for all systems where DBUS_SESSION_BUS_ADDRESS is present.

Create a script:

# notify.sh

environs=`pidof dbus-daemon | tr ' ' '\n' | awk '{printf "/proc/%s/environ ", $1}'`
export DBUS_SESSION_BUS_ADDRESS=`cat $environs 2>/dev/null | tr '\0' '\n' | grep DBUS_SESSION_BUS_ADDRESS | cut -d '=' -f2-`
export DISPLAY=:0

notify-send "It works!"

Make it executable:

$ chmod +x ~/notify.sh

Add it to crontab:

* * * * * $HOME/notify.sh

This took forever to make work on ubuntu 15.10, Had to add a source to get the users normal env vars. my display was :1 for some reason as well. Using the gnome-session first results pid for DBUS_SESSION_BUS_ADDRESS lookup.

# Crontab is
* 21 * * * /bin/sh /home/tristik/cron.sh
# cron.sh
# Notifies the user of date and time
source /home/tristik/.bashrc
pid=$(pgrep -u tristik gnome-session | head -n 1)
dbus=$(grep -z DBUS_SESSION_BUS_ADDRESS /proc/$pid/environ | sed 's/DBUS_SESSION_BUS_ADDRESS=//' )
export HOME=/home/tristik
export DISPLAY=:1
/usr/bin/notify-send 'title' "$(/bin/date)"

I have just got this to work with the cinnamon desktop on Ubuntu 15.10, using the following recipe:

if [ ! -v DBUS_SESSION_BUS_ADDRESS ]; then
  pid=$(pgrep -u $LOGNAME cinnamon-sessio)
  eval "export $(\grep -z DBUS_SESSION_BUS_ADDRESS /proc/$pid/environ)"
notify-send "$RESUME" "$INFO"

The trick was to realize that 'cinnamon-session' is too long for pgrep to find:

$ pgrep -u $LOGNAME cinnamon-session
$ pgrep -u $LOGNAME cinnamon
$ ps -a | \grep cinnamon
30789 tty2     00:00:00 cinnamon-sessio
30917 tty2     00:00:02 cinnamon-settin
30965 tty2     00:00:00 cinnamon-launch
30981 tty2     00:04:15 cinnamon
31039 tty2     00:00:00 cinnamon-killer
31335 tty2     00:00:00 cinnamon-screen
$ ps a | \grep cinnamon
 4263 pts/1    S+     0:00 grep cinnamon
30779 tty2     Ssl+   0:00 /usr/lib/gdm/gdm-x-session --run-script cinnamon-session-cinnamon
30789 tty2     Sl+    0:00 cinnamon-session --session cinnamon
30917 tty2     Sl+    0:02 /usr/lib/x86_64-linux-gnu/cinnamon-settings-daemon/cinnamon-settings-daemon
30965 tty2     Sl+    0:00 /usr/bin/python2 /usr/bin/cinnamon-launcher
30970 tty2     Sl+    0:00 /usr/lib/x86_64-linux-gnu/cinnamon-settings-daemon/csd-printer
30981 tty2     Sl+    4:16 cinnamon --replace
31039 tty2     Sl+    0:00 /usr/bin/python2 /usr/bin/cinnamon-killer-daemon
31335 tty2     Sl+    0:00 cinnamon-screensaver
$ pgrep -u $LOGNAME cinnamon-sessio

I also had to use \grep because my grep is aliased to

$ alias grep
alias grep='grep -n --color=always'

I use i3 on Ubuntu 18.04. My way to solve this is:

* * * * * XDG_RUNTIME_DIR=/run/user/$(id -u) notify-send Hey "this is dog!"


Issue caused by calling python3 in crontab with UTF-8 locale.

TL;DR: prefix call in crontab w/ locale as in:

*/5 * * * * LC_ALL=en_US.utf-8 LANG=en_US.utf-8 ~/.local/bin/watson-notify

See also click and python3:

Traceback (most recent call last):
  File "/usr/lib/python3.6/runpy.py", line 193, in _run_module_as_main
    "__main__", mod_spec)
  File "/usr/lib/python3.6/runpy.py", line 85, in _run_code
    exec(code, run_globals)
  File "/usr/lib/python3/dist-packages/watson/__main__.py", line 6, in <module>
  File "/usr/lib/python3/dist-packages/click/core.py", line 759, in __call__
    return self.main(*args, **kwargs)
  File "/usr/lib/python3/dist-packages/click/core.py", line 693, in main
  File "/usr/lib/python3/dist-packages/click/_unicodefun.py", line 123, in _verify_python3_env
    'for mitigation steps.' + extra)
RuntimeError: Click will abort further execution because Python 3 was configured to use ASCII as encoding for the environment.  Consult http://click.pocoo.org/python3/ for mitigation steps.

This system supports the C.UTF-8 locale which is recommended.
You might be able to resolve your issue by exporting the
following environment variables:

    export LC_ALL=C.UTF-8
    export LANG=C.UTF-8

Your Answer

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

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