Bash: Show Notifications from Scripts Using notify-send

📅 October 25, 2020

Are you familiar with those notification popups that appear on the Linux desktop during certain events, such as a disconnected network or a completed download?

Well, did you know that you can cause these to appear with your own messages from a bash script? This can be useful when you want to be notified of an event, such as when a user logs into your system via SSH.

This article will show a few basics about how you can create your own notifications in Linux Mint 20.

Notification Appearance

Notifications are usually installed and enabled by default in Ubuntu-based distributions. Here, we will use Linux Mint 20. A notification depends upon the chosen theme, so its appearance might change. However, the notification contents will still appear.

Default light theme in Linux Mint 20 causes notifications to appear on a light background.
Dark theme shows a dark background.
The chosen Desktop theme for the panel determines the notification theme. Change this to change the notification appearance.

 

Zenity

 

Zenity has a notification system using zenity –notification, but I have found this to be too limited.

zenity --notification --text='Greetings from Computer Land!'
Zenity’s notification system produces simple notifications.

notify-send

A much better solution is notify-send, which is available in Linux Mint 20. If your distribution does not have a notification system, then you should be able to set it up by installing notify-osd from the repository.

sudo apt install notify-osd

You can display notifications in Linux Mint 20 without installing notify-osd. If you are using a different distribution, such as Ubuntu, the techniques mentioned here should apply to notify-osd too (though not 100% tested).

Usage

It’s easy!

notify-send 'Hello, Wide World!'

This displays a simple message in the notification area of your desktop with a default icon and a default timeout that causes the message to disappear.

Let’s notify!

If you miss a notification or if you want to view past notifications, click the notification icon in the panel.

Viewing missed notifications.

This allows you to view past notifications. You can click on a notification to make it disappear, but this will not make it appear in the notification history for viewing later.

Timeout

Normally, a notification disappears after five seconds, but this can be changed with the -t option. 

notify-send -t 10000 'Hello for ten seconds'

The timeout is expressed in milliseconds, so 10 seconds is 10000 milliseconds. However, Ubuntu and Linux Mint ignore this timeout value. The message will disappear after five seconds regardless.

Add a Title

A message is fine, but let’s provide a title too. The first text argument specifies the title, and the second is the message.

notify-send 'The Story So Far...' 'Once upon a time there was a file.'
The title appears in bold, while the text appears in a normal font.

Urgency

How important is your message? There are three levels you can set the notification by using the -u option:

  • low
  • normal
  • critical
notify-send -u low 'Low urgency'
notify-send -u normal 'Normal'
Low and Normal urgency levels use a blue icon and timeout. They will appear in the missed notifications list.
notify-send -u critical 'AAAAH! I NEED YOUR ATTENTION NOW!'

On the other hand, the critical urgency should be reserved for truly important messages that you do not want to miss. When set to critical, the notification does not automatically disappear after a timeout. You must click the message to remove it.

Critical uses a red icon, and it is not added to the notification list.

More Text

We can display more than a simple message. How about command substitution?

notify-send 'Lines from /etc/passwd' "$(head /etc/passwd)"
There is little limit on what text is allowed in a notification.

Make sure to include the double quotes or else it will not work.

Newlines

We can add newlines by using the \n escape sequence.

notify-send 'Where the Wind Blows' "T'was a dark\nand\nstormy night\nin October…"
The \n will insert a newline into the text string.

Variables

We can store text in a variable and pass the variable to notify-send for display.

title='The Question'
message='To beehave or not to beehave,\nThat is the question the little bee pondered.'
notify-send "$title" "$message"
Using variables allow the message to change according to a script.

Change the Icon

So far, we have been using the default notification icons, but we can make any image appear using the -i option.

notify-send -i ~/yellowtux.png 'The Chicken and the Gravy' 'Which disappeared first: The chicken or the gravy?'
A custom icon can be added.

Take note that no matter the icon’s size, it will be shown as a small icon in the upper left part in the notification.

Also, use absolute image paths when possible. Images using relative paths would not show the image. The home path alias ~ works.

We can even display a user’s icon if one has been set. The icon is an image file stored in ~/.face. Suppose we have a user account named sonic:

notify-send -i /home/sonic/.face 'Sonic' "Look who's coming to dinner."
This icon is obtained from the user’s .face image file stored in his home directory.

 

Add a Link

How about adding a link that opens a web page when clicked?

notify-send -i ~/atari.png 'Surprise Link of the Day' 'Have you played Atari today?\nhttp://www.atariage.com'
Links can be included in notifications by using the URL.

Just add the URL starting with http. The text will be converted into a link.

Keep in mind that the link text will appear. We cannot use an HTML link like this:

notify-send -i ~/atari.png 'Surprise Link of the Day' 'Have you played Atari today?\n<a href="http://www.atariage.com">http://www.atariage.com</a>'
Notifications do not parse HTML.

Clicking the link opens the default browser to the given URL. This can be convenient should you need to provide easy access to a particular page as a result of a script decision, such as a specific kernel to download or if a page is updated.

Show a Notification When a User Logs in Via SSH

Let’s put some of this to real use. We want a notification to appear whenever a user successfully logs in via SSH. Only successful login messages are shown.

The script detected that user knuckles logged in via SSH and displayed a notification.

First, write a script. Name it whatever you like and enable its execute permission. In this example, we will name it watchssh.sh.

#!/bin/bash

tail -fn0 /var/log/auth.log |
grep --line-buffered 'Accepted' |
while read line
do
    notify-send 'SSH Login Detected' "$line"
done

Run this in a terminal for testing, and log in using a second terminal via ssh. The user knuckles must already exist on the system, and OpenSSH must be installed and listening for connections.

To log in using SSH as user knuckles:

ssh knuckles@192.168.2.1
This shows that a user has logged into the system using SSH.

By default, we see the blue icon and the notification disappears after five seconds. If we want to force the notification to remain until clicked (we might have written the script to look for a certain user to log in), we can change the urgency to critical.

Suppose we have a user account named sonic, and sonic logs in using the Nemo file manager. The script will still detect the SSH login.

A user can also log in graphically via SSH by specifying the SSH protocol and entering his username in the Nemo file manager.
When urgency is set to critical, the red icon appears, and the notification remains on the desktop until it is clicked. This way, you do not miss the notification.

The script detects the SSH login whether the user logged in from a terminal or from a file manager. As long as the connection is SSH, it is recorded in the /var/log/auth.log file in Linux Mint 20.

The script uses tail to monitor auth.log for any changes. When a user successfully logs in with SSH, there will be a line added containing the word Accepted. grep looks for this line so the while loop will display it as a notification.

Experiment with SSH and view /var/log/auth.log to see what is recorded. Many different SSH events are logged, including failed logins. For simplicity, we are only displaying a notification for each successful login.

Modifying the Script

We can show the user’s icon for improved user recognition.

!/bin/bash

tail -fn0 /var/log/auth.log |
grep --line-buffered 'Accepted' |
while read line
do
    user=$(echo "$line" | tr -s ' ' | cut -d' ' -f9)
    notify-send -i "/home/$user/.face" "$user Just Logged In"  "$line"
done

We need to add the tr -s’ ‘ in order to squeeze multiple space characters into one space character so cut -d’ ‘ -f9 can grab the correct username field. When the date changes from single to double digits, the number of spaces changes between the month and the day.

Now, when a user logs in, his icon (if it exists) will also appear in the notification.

User sonic logged in using SSH.

The urgency was left at its default so the notification will disappear after the timeout. We can view other logins too. Suppose was also have the user accounts knuckles and tails. They logged in, but we missed them. We can view the logins from the notification list.

“Who logged in while I was away?” The notification listing will show missed notifications.

Startup Script

So far, the script was running in a terminal, but we can add it to the list of Startup Applications so it runs in the background to monitor for SSH logins automatically.

System Settings in Linux Mint 20. Add the SSH watch script so it will automatically run behind the scenes. Of course, this technique is dependent upon this specific user logging in first, which is what we want to happen.

Conclusion

Notifications are fun because they can integrate your script into the operating system, but use them sparingly unless you want to annoy your users.

Above all, experiment with various options to see what happens, and have fun!

Advice to the wise.

, , ,

  1. Leave a comment

Leave a comment