Skip directly to content

Pop-up notification from the command line

on Sat, 2010-07-31 01:40

Notifying from the command line with notify-send.
If you are running Ubuntu on your desktop, you certainly have seen the ephemeral balloons that pop-up with notifications. These are designed to make you aware of something, e.g. that you have email, without interrupting your work with a window that you must close.

These balloons, also called bubbles, are shown by a notification daemon, that receives messages from other programs, queue them and presents them in a overlay for a short period of time. On Ubuntu (from 9.04) the notification daemon is called Notify OSD.

Many GUI programs use this desktop notification service to provide unobtrusive information about progress, events and such things. Wouldn't it be nice if you could send such messages from your own Bash scripts? Well, you can with notify-send.

Installing notify-send

Notify-send is a small program that allow you to send notifications to any notification agent that implements the Desktop Notifications Specification, for instance Notify OSD.

To get notify-send on Ubuntu, just install the package libnotify-bin.

sudo apt-get install libnotify-bin

Sending desktop notifications from the command line

Let's try it! Start with the bare minimum. You should see a balloon pop-up in the top right corner of the screen saying "Hello World!". It will stay for about 15 seconds, and then fade away.

notify-send "Hello World!"

If you give a second argument, it will be shown as a body text, with the first one as a summary.

notify-send "This is a summary" "And this is the body text. If it is long enough, Notify OSD will wrap it for you."

What happens if you send two messages directly after each other? They will not be shown at the same time. First message one will be shown, and then message two. This is because Notify OSD queues messages and shown them one after the other.

notify-send "Message one" & notify-send "Message two"

Add an icon

If you want to add one of the icons underneath /usr/share/icons to the notification, you just have to add the option -i followed by the name of the icon without the file extension.

notify-send -i face-cool "I'm cool."

You could also use an image from outside the icons directory by supplying the full path to the file.

notify-send -i /usr/share/pixmaps/gnome-irc.png "Demonstration" \
"This is a desktop notification from the command line."

Don't go away

The desktop notifications are designed to be as unobtrusive as possible. But sometimes you want the notification to as obtrusive as possible. You can accomplish that by adding the option -t 0. That will bring up a traditional dialog box that you must click away.

notify-send -t 0 "I want go away until you click on me."

But for this purpose you should consider the built in Zenity instead.

Unsupported options

It's important to remember that notify-send and the Notify OSD are two separate programs that are independent of each other. Both are designed to be compatible with the Desktop Notifications Specification, but while notify-send implements everything in the specification, Notify OSD currently implements only a minimum of the specification. As result, many of the options supported by notify-send, e.g. -u <level>, where <level> is low, normal or critical to indicate the urgency level, and -t <time>, where <time> is the number of milliseconds at which to expire the notification, are without effect (on Ubuntu 10.04 at least).

Another consequence is that you can't use markup in the body, although it is recommended by the specification.

Line break in the body of notify-send

Related to markup is escape sequences, such as the control character newline (LF) used to make a line break. When you write a string like "This is the first line.\nAnd this is the second.", you expect the two sentences to be on different lines. But that's not what Notify OSD do.

notify-send "\n doesn't work" "This is the first line.\nAnd this is the second."

As far as the specification goes, this is not an error. Fortunately there are two methods to work around this predicament.

The first is to literally write the control character. To do that, hit CTRL + V followed by the control character, for instance CTRL + M for ńewline. The character is echoed back as ^M but is actually a newline character and not the two characters ^ and M.

notify-send "Escape character for newline doesn't work" "This is the first line.^MAnd this is the second."

The second solution, and maybe the safest in scripts, is to use another command, e.g. echo or printf, to create the string. The strange use of double quotation mark within another double quotation mark pair is in fact correct and necessary.

notify-send "Escape character for newline doesn't work" \
"$(echo -e "This is the first line.\nAnd this is the second.")"

Example of use

So, for what should you use this nifty command utility? You could use it, as I did, to write a script that notifies when email arrives to your Gmail or Google Apps account. Here follows some more examples.

Give progress report from an exhaustive script.

#!/usr/bin/env bash
notify-send "Start task 1."
...
notify-send "End task 1. Start task 2."
...
notify-send "End task 2. Start task 3."
...
notify-send "End task 3. All tasks finished."

Notify yourself when a long lasting command has finished.

make && notify-send "Successfully compiled the kernel" || \
notify-send "Error while compiling the kernel"

Use it as a timer.

(sleep 45m; notify-send -t 0 "Laundry done!") &

Don't forget to go to bed.

echo 'notify-send "Go to bed!"' | at midnight

Follow what's going on on your machine.

(tail -n0 -f /var/log/syslog | while read line; do notify-send "System Message" "$line"; done) &

Make a Bash function to play with:

send() { notify-send "$*" "$(eval "$*" 2>/dev/null)"; }
send ls /
send df -hTx tmpfs
send cat /proc/loadavg
echo 'scale=5; 365 / 12 / 7' | send bc

Well, that's it folks. Hope you enjoy notify-send.

Post new comment