10 Tools To Add Some Spice To Your UNIX/Linux Shell Scripts

There are some misconceptions that shell scripts are only for a CLI environment. You can efficiently use various tools to write GUI and network (socket) scripts under KDE or Gnome desktops. Shell scripts can make use of some of the GUI widget (menus, warning boxes, progress bars, etc.). You can always control the final output, cursor position on the screen, various output effects, and more. With the following tools, you can build powerful, interactive, user-friendly UNIX / Linux bash shell scripts.

Creating GUI application is not an expensive task but a task that takes time and patience. Luckily, both UNIX and Linux ships with plenty of tools to write beautiful GUI scripts. The following tools are tested on FreeBSD and Linux operating systems but should work under other UNIX like operating systems.

1. notify-send Command

The notify-send command allows you to send desktop notifications to the user via a notification daemon from the command line. This is useful to inform the desktop user about an event or display some form of information without getting in the user’s way. You need to install the following package on a Debian/Ubuntu Linux using apt command/apt-get command:
$ sudo apt-get install libnotify-bin
CentOS/RHEL user try the following yum command:
$ sudo yum install libnotify
Fedora Linux user type the following dnf command:
$ sudo dnf install libnotify
In this example, send simple desktop notification from the command line, enter:

## send some notification ##
notify-send "rsnapshot done :)"

Sample outputs:

Fig:01: notify-send in action

Here is another code with additional options:
....
alert=18000
live=$(lynx --dump http://money.rediff.com/ | grep 'BSE LIVE' | awk '{ print $5}' | sed 's/,//g;s/\.[0-9]*//g')
[ $notify_counter -eq 0 ] && [ $live -ge $alert ] && { notify-send -t 5000 -u low -i   "BSE Sensex touched 18k";  notify_counter=1; }
...

Sample outputs:

Fig.02: notify-send with timeouts and other options

Where,
  • -t 5000: Specifies the timeout in milliseconds ( 5000 milliseconds = 5 seconds)
  • -u low : Set the urgency level (i.e. low, normal, or critical).
  • -i gtk-dialog-info : Set an icon filename or stock icon to display (you can set path as -i /path/to/your-icon.png).

For more information on use of the notify-send utility, please refer to the notify-send man page, viewable by typing man notify-send from the command line:
man notify-send

#2: tput Command

The tput command is used to set terminal features. With tput you can set:

  • Move the cursor around the screen.
  • Get information about terminal.
  • Set colors (background and foreground).
  • Set bold mode.
  • Set reverse mode and much more.

Here is a sample code:

#!/bin/bash
 
# clear the screen
tput clear
 
# Move cursor to screen location X,Y (top left is 0,0)
tput cup 3 15
 
# Set a foreground colour using ANSI escape
tput setaf 3
echo "XYX Corp LTD."
tput sgr0
 
tput cup 5 17
# Set reverse video mode
tput rev
echo "M A I N - M E N U"
tput sgr0
 
tput cup 7 15
echo "1. User Management"
 
tput cup 8 15
echo "2. Service Management"
 
tput cup 9 15
echo "3. Process Management"
 
tput cup 10 15
echo "4. Backup"
 
# Set bold mode
tput bold
tput cup 12 15
read -p "Enter your choice [1-4] " choice
 
tput clear
tput sgr0
tput rc

Sample outputs:

Fig.03: tput in action

For more detail concerning the tput command, see the following man page:
man 5 terminfo
man tput

#3: setleds Command

The setleds command allows you to set the keyboard leds. In this example, set NumLock on:

setleds -D +num

To turn it off NumLock, enter:

setleds -D -num
  • -caps : Clear CapsLock.
  • +caps : Set CapsLock.
  • -scroll : Clear ScrollLock.
  • +scroll : Set ScrollLock.

See setleds command man page for more information and options:
man setleds

#4: zenity Command

The zenity commadn will display GTK+ dialogs box, and return the users input. This allows you to present information, and ask for information from the user, from all manner of shell scripts. Here is a sample GUI client for the whois directory service for given domain name:

#!/bin/bash
# Get domain name
_zenity="/usr/bin/zenity"
_out="/tmp/whois.output.$$"
domain=$(${_zenity} --title  "Enter domain" \
	            --entry --text "Enter the domain you would like to see whois info" )
 
if [ $? -eq 0 ]
then
  # Display a progress dialog while searching whois database
  whois $domain  | tee >(${_zenity} --width=200 --height=100 \
  				    --title="whois" --progress \
			            --pulsate --text="Searching domain info..." \
                                    --auto-kill --auto-close \
                                    --percentage=10) >${_out}
 
  # Display back output
  ${_zenity} --width=800 --height=600  \
	     --title "Whois info for $domain" \
	     --text-info --filename="${_out}"
else
  ${_zenity} --error \
	     --text="No input provided"
fi

Sample outputs:

Fig.04: zenity in Action

See the zenity man page for more information and all other supports GTK+ widgets:
zenity --help
man zenity

#5: kdialog Command

kdialog is just like zenity but it is designed for KDE desktop / qt apps. You can display dialogs using kdialog. The following will display message on screen:

kdialog --dontagain myscript:nofilemsg --msgbox "File: '~/.backup/config' not found."

Sample outputs:

Fig.05: Suppressing the display of a dialog

See shell scripting with KDE Dialogs tutorial for more information.

#6: Dialog

Dialog is an application used in shell scripts which displays text user interface widgets. It uses the curses or ncurses library. Here is a sample code:

#!/bin/bash
dialog --title "Delete file" \
--backtitle "Linux Shell Script Tutorial Example" \
--yesno "Are you sure you want to permanently delete \"/tmp/foo.txt\"?" 7 60
 
# Get exit status
# 0 means user hit [yes] button.
# 1 means user hit [no] button.
# 255 means user hit [Esc] key.
response=$?
case $response in
   0) echo "File deleted.";;
   1) echo "File not deleted.";;
   255) echo "[ESC] key pressed.";;
esac

See the dialog man page for details:
man dialog

A Note About Other User Interface Widgets Tools

UNIX and Linux comes with lots of other tools to display and control apps from the command line, and shell scripts can make use of some of the KDE / Gnome / X widget set:

  • gmessage – a GTK-based xmessage clone.
  • xmessage – display a message or query in a window (X-based /bin/echo)
  • whiptail – display dialog boxes from shell scripts
  • python-dialog – Python module for making simple Text/Console-mode user interfaces

#7: logger command

The logger command writes entries in the system log file such as /var/log/messages. It provides a shell command interface to the syslog system log module:

logger "MySQL database backup failed."
tail -f /var/log/messages
logger -t mysqld -p daemon.error "Database Server failed"
tail -f /var/log/syslog

Sample outputs:

Apr 20 00:11:45 vivek-desktop kernel: [38600.515354] CPU0: Temperature/speed normal
Apr 20 00:12:20 vivek-desktop mysqld: Database Server failed

See howto write message to a syslog / log file for more information. Alternatively, you can see the logger man page for details:
man logger

#8: setterm Command

The setterm command can set various terminal attributes. In this example, force screen to turn black in 15 minutes. Monitor standby will occur at 60 minutes:

setterm -blank 15 -powersave powerdown -powerdown 60

In this example show underlined text for xterm window:

setterm -underline on;
echo "Add Your Important Message Here"
setterm -underline off

Another useful option is to turn on or off cursor:

setterm -cursor off

Turn it on:

setterm -cursor on

See the setterm command man page for details:
man setterm

#9: smbclient: Sending Messages To MS-Windows Workstations

The smbclient command can talk to an SMB/CIFS server. It can send a message to selected users or all users on MS-Windows systems:

smbclient -M WinXPPro <<eof
Message 1
Message 2
...
..
EOF

OR

echo "${Message}" | smbclient -M salesguy2

See smbclient man page or read our previous post about “sending a message to Windows Workstation” with smbclient command:
man smbclient

#10: Bash Socket Programming

Under bash you can open a socket to pass some data through it. You don’t have to use curl or lynx commands to just grab data from remote server. Bash comes with two special device files which can be used to open network sockets. From the bash man page:

  1. /dev/tcp/host/port – If host is a valid hostname or Internet address, and port is an integer port number or service name, bash attempts to open a TCP connection to the corresponding socket.
  2. /dev/udp/host/port – If host is a valid hostname or Internet address, and port is an integer port number or service name, bash attempts to open a UDP connection to the corresponding socket.

You can use this technquie to dermine if port is open or closed on local or remote server without using nmap or other port scanner:

# find out if TCP port 25 open or not
(echo >/dev/tcp/localhost/25) &>/dev/null && echo "TCP port 25 open" || echo "TCP port 25 close"

You can use bash loop and find out open ports with the snippets:

echo "Scanning TCP ports..."
for p in {1..1023}
do
  (echo >/dev/tcp/localhost/$p) >/dev/null 2>&1 && echo "$p open"
done

Sample outputs:

Scanning TCP ports...
22 open
53 open
80 open
139 open
445 open
631 open

In this example, your bash script act as an HTTP client:

#!/bin/bash
exec 3<> /dev/tcp/${1:-www.cyberciti.biz}/80
 
printf "GET / HTTP/1.0\r\n" >&3
printf "Accept: text/html, text/plain\r\n" >&3
printf "Accept-Language: en\r\n" >&3
printf "User-Agent: nixCraft_BashScript v.%s\r\n" "${BASH_VERSION}"   >&3
printf "\r\n" >&3
 
while read LINE <&3
do
   # do something on $LINE
   # or send $LINE to grep or awk for grabbing data
   # or simply display back data with echo command
   echo $LINE
done

See the bash man page for more information:
man bash

A Note About GUI Tools and Cronjob

You need to request local display/input service using export DISPLAY=[user’s machine]:0 command if you are using cronjob to call your scripts. For example, call /home/vivek/scripts/monitor.stock.sh as follows which uses zenity tool:
@hourly DISPLAY=:0.0 /home/vivek/scripts/monitor.stock.sh

Have a favorite UNIX tool to spice up shell script? Share it in the comments below.

🐧 If you liked this page, please support my work on Patreon or with a donation.
🐧 Get the latest tutorials on SysAdmin, Linux/Unix, Open Source & DevOps topics via:
CategoryList of Unix and Linux commands
File Managementcat
FirewallAlpine Awall CentOS 8 OpenSUSE RHEL 8 Ubuntu 16.04 Ubuntu 18.04 Ubuntu 20.04
Network Utilitiesdig host ip nmap
OpenVPNCentOS 7 CentOS 8 Debian 10 Debian 8/9 Ubuntu 18.04 Ubuntu 20.04
Package Managerapk apt
Processes Managementbg chroot cron disown fg jobs killall kill pidof pstree pwdx time
Searchinggrep whereis which
User Informationgroups id lastcomm last lid/libuser-lid logname members users whoami who w
WireGuard VPNAlpine CentOS 8 Debian 10 Firewall Ubuntu 20.04
111 comments… add one
  • Andriy Feb 29, 2016 @ 15:19

    I want to share my version of a dialog-like tool with the hope it will be helpful for others: https://github.com/martynets/dialogbox
    It makes another approach. It does not build a predefined dialog based on command line options but it is a scriptable engine which is capable to build flexible dialogs.

  • Mike Schwager Aug 21, 2015 @ 17:18

    #10 is cool! It’s in the man page, but I’ve always skipped by it… no more!

    Thanks.

  • Andrew M Feb 6, 2015 @ 9:18

    Thank you very much for posting these eye-opening examples.

  • Eddy Martin Nov 29, 2014 @ 23:50

    I can’t believe nobody suggested Yad!
    https://code.google.com/p/yad/
    http://sourceforge.net/projects/yad-dialog/
    “Yad (yet another dialog) is a fork of Zenity with many improvements, such as custom buttons, additional dialogs, pop-up menu in notification icon and more. ”

    Much more powerful and flexible than Zenity or others.

  • Danos Oct 22, 2014 @ 7:26

    Hi Vivek,

    Thank your for very useful article. In the first example I had to add “info” to run the second script:

    $ […] notify-send -t 5000 -u low -i info “BSE Sensex touched 18k […]

    Otherwise the “no summary” error was reported by bash (Ubuntu 12.04 LTS).

    Best regards

  • Ali Sep 27, 2014 @ 17:53

    my script uses tput and works fine when runs on terminal, but when it is ran via cronrtab, it does not work properly.

  • Gregg Leventhal May 2, 2014 @ 21:24

    Who uses X Windows (or any windows manager) these days ?!? 🙂

    • Chris F.A. Johnson Oct 21, 2014 @ 21:42

      Who? Almost every desktop *ix user.

Leave a Reply

Your email address will not be published. Required fields are marked *

Use HTML <pre>...</pre>, <code>...</code> and <kbd>...</kbd> for code samples.