📅 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.
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!'
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.
If you miss a notification or if you want to view past notifications, click the notification icon in the panel.
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.'
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'
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.
More Text
We can display more than a simple message. How about command substitution?
notify-send 'Lines from /etc/passwd' "$(head /etc/passwd)"
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…"
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"
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?'
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."
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'
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>'
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.
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
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.
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.
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.
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.
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!