Hack and / - Message for You Sir

Why check for new e-mail every minute when a script can do it for you? Learn how to trigger desktop notifications in your own scripts.
Consider Yourself Notified

I used to use OSD notifications for all sorts of scripts on my system, including one that notified me when I got new e-mail. It worked fine, but sometimes I'd rather get a notification that's a little easier to ignore. Although I suppose I could move my OSD alert to a corner of the screen, then it would be almost too easy to miss. I wanted something that would get my attention but also would not get in the way. Currently, I use GNOME as my desktop environment, and I realized that its desktop notifications were ideal. They caught the corner of my eye, but they didn't jump in front of everything else I'm doing.

The library GNOME uses for notifications is the appropriately named libnotify, and it turns out, it was trivial to migrate my notifications from osd_cat to libnotify using the notify-send command. Because I already was using GNOME, the program already was installed. If it's not in your case, look for a package named libnotify-bin or search your package manager for notify-send.

The syntax for notify-send is substantially simpler than osd_cat, as the message's location and font already are handled for you. Here's a simple example:

$ notify-send "Message for you Sir" "Hello World"

This will pop up a basic message in a notification window on my desktop. The first set of quotes specifies the title of the message, and the next set of quotes defines the body of the message.

Of course, when I use notify-send to alert me of new e-mail, I use something a bit fancier. If you'd like to set up e-mail notification for yourself, here's a more simplified version of my personal script to get you started. First, set up fetchmail so that it can connect to your IMAP server. Just as a warning, don't ever run fetchmail without the -c option, unless you do want to download all your mail to your local machine. Once fetchmail is configured, you can test that it works with fetchmail -c:

$ fetchmail -c
991 messages (990 seen) for kyle at mail.example.net 
 (folder INBOX).
530 messages (530 seen) for kyle at mail.example.net 
 (folder INBOX.nblug).
284 messages (284 seen) for kyle at mail.example.net 
 (folder INBOX.linuxjournal).

As you can see, there's a new message that I haven't seen in my INBOX folder. All you need to do now is write a script that will execute fetchmail -c, parse the output, and tally the total and seen messages. If the totals differ, you have new mail and can execute notify-send with the appropriate message. Here's a quick Perl script that goes a step further and keeps track of each folder with new messages as well, so it can list them and their tally:


open FETCHMAIL, "/usr/bin/fetchmail -t 10 -c 2>/dev/null 
 ↪|" or die "Can't run fetchmail: $!\n";

   if(/^(\d+) messages \((\d+) seen.*?folder (.*?)\)/){
   # keep a running total of all messages and seen messages
      $messages+=$1; $seen+=$2; 
      $folder =~ s/INBOX\.//; # strip the INBOX. 
                              # from the folder names
# If there are more messages than seen messages, 
# store the difference
   if($1 > $2){
      $folders{$folder} = $1 - $2;

$total = $messages - $seen;

if($total > 0){
   foreach $folder (sort { $folders{$a}<=>$folders{$b} 
   ↪} keys %folders){
      push @list, "$folder:$folders{$folder}";
   $output = join " ", @list;
   system ("notify-send -u low -i /usr/share/pixmaps/mutt.xpm 
   ↪-t 5000 'New Mail' '$output'");

Notice I added a few extra options to my notify-send in this example. First, I used the -u option so I could set the urgency of the message to either low, normal or critical. The -i option lets me specify an icon to add to the image, so I picked my system's mutt icon, because that's the program I'll use to read the mail. Next, I used the -t option so I could set the timeout for the message in milliseconds. Finally, I added the title and body of my message.

If you set this up yourself, all you have to do now is save the script and add it to your user's crontab so it will run however often you want to check for new mail. I also recommend adding some sort of throttling to the script, so it will notify you of a current batch of new mail only a few times. That way if you can't get to your e-mail immediately, the notifications won't become annoying.

Don't Forget to Blink

Desktop notifications are great, but what happens if I'm not looking at the screen when a notification appears? Sure, if the script runs every minute, I eventually will see it, but I set up throttling for those sorts of notifications. I came up with a notification that's even less intrusive than libnotify, yet it will alert me of new mail even if my screen idles out and goes blank: my keyboard LEDs.

Now there certainly is nothing new about using keyboard LEDs for notifications—after all, their intended purpose is to notify you about the state of your caps lock, num lock and scroll lock keys. But, how often do you use your scroll lock or even your caps lock these days? I mean, a number of my friends even went full-UNIX nerd on me and remapped caps lock back to the Ctrl key. Your keyboard LEDs are three notification areas begging to be used, and Linux has plenty of utilities that can use them.

I've tried a few different tools that let me control the keyboard LEDs from a script, but I've settled on blinkd as my favorite. This program runs as a dæmon (see the d at the end?) when the system starts up, and what I like about it is that it not only lets you control all three keyboard LEDs, but you also can set a number of times for it to blink the LED—perfect for keeping track of new e-mail messages.

To install blinkd, look for the package of the same name with your package manager. Once it's installed, if your package manager didn't automatically start it, run /etc/init.d/blinkd start. After the dæmon is running, you can control the LEDs via the blink command. The syntax is pretty simple. For instance, if I want to blink the scroll lock key a single time, I would type:

$ blink -s -r 1

The -s argument tells it to activate the scroll lock LED, and -r tells it how many times to blink before it pauses. I also could have used -c or -n instead of -s to blink the caps lock or num lock LEDs, respectively. You also can set the number of blinks to 0 to turn off blinking for a specific LED, or type blink -r 0 to turn off blinking for all of the LEDs.

Because the script I wrote above already has the total number of new messages, it's trivial to have my scroll lock key blink that number of times. Here's the modified section of my script:

if($total > 0){
   foreach $folder (sort { $folders{$a}<=>$folders{$b} 
   ↪} keys %folders){
      push @list, "$folder:$folders{$folder}";
   $output = join " ", @list;
   system ("notify-send -u low -i /usr/share/pixmaps/mutt.xpm 
   ↪-t 5000 'New Mail' '$output'");
   system ("blink -s -r $total");
else {
   system ("blink -r 0");

The great thing about using a keyboard LED for notifications is that you end up noticing it out of the corner of your eye, especially if you left your computer for a minute, yet it won't steal your focus completely if you are working. I also like that I can tell how many new messages I have at a glance. If you want to extend the script further, I'd recommend separating your folders into regular and high priorities, and make the script blink different LEDs depending on which folders have new mail. If you have multiple e-mail accounts, you might even want multiple versions of the script with an LED assigned to each account. I'd say the possibilities are endless, but they aren't. You have only three LEDs to play with.

In this column, I've mostly mentioned checking for e-mail as a candidate for desktop notifications, but there are any number of other things for which you might want notifications, such as system temperature, LEDs triggered by the local mail or printer queues, notices triggered by RSS feed (or dare I say it, Twitter) updates, or even desktop notifications tripped by your server monitoring system. Why keep all those dæmons running silently in the background when you can make them speak up when there's something to report?

Kyle Rankin is a Systems Architect in the San Francisco Bay Area and the author of a number of books, including The Official Ubuntu Server Book, Knoppix Hacks and Ubuntu Hacks. He is currently the president of the North Bay Linux Users' Group.


Kyle Rankin is Chief Security Officer at Purism, a company focused on computers that respect your privacy, security, and freedom. He is the author of many books including Linux Hardening in Hostile Networks, DevOps Troubleshooting and The Official Ubuntu


Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.


Treah's picture

Unable to locate this blink program....
One of the main issues of this program is that it has such a generic name. There was a kernel driver by this name that was removed because it was buggy and problematic. I however am not using a distro so maybe the programs is listed somewhere in a respoistory but a google search turns up no sources or anything for it. If anyone is following this article maybe you can post sources for it or post a location for the sources. If nothing gets posted I may consider writing something small in c if its even possible.


linuxgeek96's picture

I'm using fedora 12, but I can't seem to find blink in any packages.
Any suggestions?