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

Fig:01: notify-send in action

Here is another code with additional options:

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

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


  • -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:

# 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

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:

# Get domain name
domain=$(${_zenity} --title  "Enter domain" \
	            --entry --text "Enter the domain you would like to see whois info" )
if [ $? -eq 0 ]
  # 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}"
  ${_zenity} --error \
	     --text="No input provided"

Sample outputs:

Fig.04: zenity in Action

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

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:

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.
case $response in
   0) echo "File deleted.";;
   1) echo "File not deleted.";;
   255) echo "[ESC] key pressed.";;

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


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}
  (echo >/dev/tcp/localhost/$p) >/dev/null 2>&1 && echo "$p open"

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:

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 something on $LINE
   # or send $LINE to grep or awk for grabbing data
   # or simply display back data with echo command
   echo $LINE

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.

🐧 Get the latest tutorials on Linux, Open Source & DevOps via RSS feed or Weekly email newsletter.

🐧 111 comments so far... add one
CategoryList of Unix and Linux commands
Disk space analyzersdf ncdu pydf
File Managementcat tree
FirewallAlpine Awall CentOS 8 OpenSUSE RHEL 8 Ubuntu 16.04 Ubuntu 18.04 Ubuntu 20.04
Network UtilitiesNetHogs dig 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
  • Mike Williamson Apr 19, 2010 @ 22:22

    Awesome! Thanks for putting that together! Very useful stuff.

  • Marco Diego Aurélio Mesquita Apr 19, 2010 @ 23:36

    #10 does not work on ubuntu. 🙁

    • Sam Watkins Apr 20, 2010 @ 0:27

      Maybe you were using dash (Ubuntu’s /bin/sh) not bash. Try it with bash!
      As for grep | awk, I like it. Pipelines with lots of simple components are fine, and it’s easy to understand. The person who stopped reading missed a great article.

      • Thanassis Apr 20, 2010 @ 8:58

        Output from “man bash | grep -A 12 tcp | head -11”:

        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.
        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.

        NOTE: Bash, as packaged for Debian, does not support using the /dev/tcp
        and /dev/udp files.

        So, as you see, Debian (and thus, Ubuntu) can’t make use of #10 …

        • Anonymous Apr 20, 2010 @ 9:27

          Ubuntu v9.10 user here 🙂

          echo $BASH_VERSION
          lsb_release -d
          Description: Ubuntu 9.10
          echo >/dev/tcp/localhost/22 && echo "ssh open"
          ssh open

        • Chris F.A. Johnson Mar 1, 2012 @ 19:44

          There’s nothing stopping you from downloading the bash source and compiling a version with sockets enabled.

    • Chris F.A. Johnson Apr 7, 2011 @ 19:57

      The Debian version of bash has the socket capability removed.

      The Mandrive version has the builtin time command removed.

      There may be other stupidites perormed by distros. That’s why I always build bash from source.

    • Tamás Pál Nov 19, 2014 @ 11:56

      Debian built version of bash had the socket feature removed, because they decided, that netcat(1) provides the same feature (and probably more secure implementation wise).

      Pretty much any distros based on Debian, who take the source from them, has the feature disabled.

      And personally I don’t blame them, proper networking is a major headache to do right, can be a security hazard, and it’s more or less outside of the scope of what a shell should do. And if you want something with cryptography, you need those tools too.

      *goes back to work grumbling about the damn kids an their music*

  • CC Apr 20, 2010 @ 0:10

    I stopped reading after #1. grep | awk is almost never required. Learn the tools before claiming proficiency.

    • Anonymous Apr 20, 2010 @ 3:41

      Grace us who are unworthy with your grepless/awkless version. I suppose you use perl, which is *never* required. Or do you apt-get some one-off program that just barley works on one particular Ubunt^W Linux distribution…

      • Eugéne Apr 21, 2010 @ 4:52

        CC was being ungracious, but to answer Anon’s question:

        lynx –dump http://money.rediff.com/ | grep ‘BSE LIVE’| sed ‘s/^ *//’| tr -s ” “| cut -d” ” -f 5

        would do the job just fine…

        • hwertz Apr 22, 2010 @ 4:46

          Sure it WOULD do the job fine. But it also is not particularly better than the initial version (also it still uses grep.) I don’t know what CC is complianing about, grep and awk are perhaps not REQUIRED, but so what? UNIX gives multiple ways to get almost anything done, so the programmer can chose the one they prefer. I see 0 problems with using grep & awk if the user desires. I must admit, Eugene, I like to use tr & cut too 8-).
          Quite nice article!

          • Chris F.A. Johnson Apr 7, 2011 @ 20:02

            grep is not needed:

            lynx -dump http://money.rediff.com/ | sed -n ‘/BSE LIVE/s/^ *//p’| tr -s “” | cut -d” ” -f 5

        • borzole Apr 22, 2010 @ 9:09

          Not quite. The idea of CC was that
          grep ‘BSE LIVE’ | awk ‘{ print $5}’
          could by writed using only awk:
          awk ‘/BSE LIVE/{ print $5}’

          BTW one more version:
          lynx –dump http://money.rediff.com/ | awk ‘/BSE LIVE/{ print $5}’ | tr -d “,” | cut -d’.’ -f1

          • 🐧 nixCraft Apr 22, 2010 @ 10:51

            You can short it further:

            lynx --dump http://money.rediff.com/ | awk '/BSE LIVE/{ gsub(/,|.[0-9]+/, ""); print $5}'

            I can even ignore lynx and use bash sockets. There are multiple ways to solve the same problem.

            • borzole Apr 22, 2010 @ 12:25

              One more version. Maybe not so short, but in pure sed

              cat >cmd.sed<<__EOF__
              /BSE LIVE/{
              	#   [20]Update Now BSE LIVE      17573.99     +101.43    +0.58%
              	#^-------------1---------------^ ^-2-^.^-----------3-----------^
              	s/(.*) ([0-9]*).([0-9]* .*)/2/g
              lynx --dump http://money.rediff.com/ | sed -n -f cmd.sed
    • Anonymous Apr 20, 2010 @ 5:29

      As a sysadmin of multiple architectures, portability is generally my main concern. Sure each shell has special features, but my scripts have to run in ksh, bash, and sh as required. Pipelines with grep/sed/awk make my job easier and allows my scripts run in more than just one brand of shell.

    • Joerg Paysen Apr 20, 2010 @ 5:52

      What is your alternative for #1 grep | awk ?

    • Anonymous Apr 20, 2010 @ 8:09

      Yeah, so what’s your version? Show me the money.

      • Anonymous Apr 20, 2010 @ 8:18

        awk ‘/BSE LIVE/{ print $5}’

    • Li chyun Apr 20, 2010 @ 9:49

      Thanks you stopped there — why dont you left w/o writing a comment.
      It seems your only purpose is to write comment! God may forgive u r sins.

  • Sam Watkins Apr 20, 2010 @ 0:25

    thanks for the great article Vivek, I learned a lot from it! 🙂

  • steve Apr 20, 2010 @ 0:39

    Very nice list there. Do like the quick local open ports lister

  • MikeFM Apr 20, 2010 @ 1:55

    You’re biggest mistake, I think, is in assuming programs should communicate with end-users. I make scripts to do things I don’t want to have to deal with manually AT ALL. I don’t want to know when they run, what they’re doing, or if something went wrong. I want them to take care of it all for me and just keep things happy. If I personally was involved in what my scripts were doing I’d be wasting hours a day. If something really bad happens I’ll know because my system loggers will start bugging the crap out of me. (Really fun when a chain of errors spreads across many systems – oooh look 100,000 messages waiting in my inbox.)

    • roche Apr 24, 2010 @ 21:45

      Wait wait even Bash has builtin function in order to read variables from stdin.

      Scripting language can be used for a wide range of uses even to interact with the users

    • Keilaron Sep 3, 2010 @ 22:00

      Your biggest mistake, I think, is assuming that all shell scripts are used solely for automated jobs 😉

  • Phil Ekstrom Apr 20, 2010 @ 2:42

    Great stuff. I am not quite yet using *nix, so wanted to download the PDF version. The attempt got me a 404 error.

  • Jay Apr 20, 2010 @ 2:57

    Basically a Linux list for the most part, not unix. /bin/bash gives it away (and the bashisms in the zenity example), also *bash* doesn’t come with /dev/{tcp,udp}, that is Linux.

    • Thanassis Apr 20, 2010 @ 9:01

      Wrong, Jay.
      A simple “man bash” followed by /tcp shows it. Unfortunately, it doesn’t work under Debian/Ubuntu, since this functionality is disabled by the Debian maintainer of bash.

  • lowell Apr 20, 2010 @ 3:19

    Kind of annoyed that of the 9 utilities listed, only 3 of them come with Mac OS X, which, unlike your test systems, is an actual UNIX-certified system. In other words, it was implied that these were standardized utilities, when they’re not. Oh well, I’m sure I can still find them if I really need them. =/

    • MikeFM Apr 20, 2010 @ 9:10

      Unfortunately Mac OS runs a nasty crippled version of Unix instead of Linux inside. Is highly frustrating sometimes. At least it isn’t as retarded as trying to use AIX. Using AIX makes me want to install Linux really REALLY badly but sadly it’s required for the service I run on it. I always wonder what is wrong with these other Unix platforms that they haven’t adopted all the improvements that have made it into Linux and the GNU tools.

      • frishrash Apr 20, 2010 @ 9:36

        Mike, AIX is the most powerful unix platform I’ve ever worked with. I don’t want to get into semi-religious arguments, and I like linux too, but when it comes to servers stability, hardware management, workload management, etc.. it’s leading operating system if not the best.

        Sure, it lacks some of the GNU tools by default but you can find almost everything you need on AIX Linux Toolbox CD. Anyway I think AIX is mainly used in servers markets, so desktop utilities are usually irrelevant.

        And I’m not working for IBM, nor got any shares 🙂

      • od Apr 20, 2010 @ 16:24

        Aww.. why don’t you go home and play with your penguin doll before the red demon starts poking you with pitchfork.

    • Leaman Crews Apr 20, 2010 @ 16:03

      Mac OS X is missing a lot of commands you would expect to find in both Linux and *BSD out of the box. watch is the one I miss the most when working on OS X.

      Fact of the matter is that OS X is Unix certified (with 10.5 or higher on x86 hardware ONLY), but what does that really mean if the tools you expect from a standard *nix distribution aren’t there by default? (And yes, I know how to get them all with fink, macports or compiling them myself.)

    • jason Dec 7, 2011 @ 3:40

      hey, AIX is awesome.. runs rings around any other OS… try and find me a OS where you can dynamically add and remove CPU and memory and storage on the fly without having to stop/start apps. And the hardware is awesome.
      And ksh is as good as any other shell, it has internal arithmatic and can perform nested loops.
      I’d like to hear you come up with a better real UNIX OS that can do what AIX and pSeries hardware can do…

      Oh, BTW, I liked this article.

      • Ryan Dec 13, 2012 @ 19:59

        “try and find me a OS where you can dynamically add and remove CPU and memory and storage on the fly without having to stop/start apps.”

        You mean like Linux?

        CPU hotplug: http://www.cyberciti.biz/faq/debian-rhel-centos-redhat-suse-hotplug-cpu/
        RAM hotplug: http://lhms.sourceforge.net/
        Storage hotswap/hotplug is pretty standard in modern operating systems.

        Granted, all three of the above are hardware-dependent, but it is indeed possible under Linux so long as the necessary kernel support is compiled in.

  • jack Apr 20, 2010 @ 3:27

    Really good list. I’m going to bookmark this one. Thanks a lot.

  • Gaurish Apr 20, 2010 @ 5:08

    Does notify-send work with KDE4?

    • cipper Apr 20, 2010 @ 9:19

      [QUOTE]Does notify-send work with KDE4?[QUOTE]
      use this:
      kdialog –passivepopup “HI!” 3

  • frishrash Apr 20, 2010 @ 6:24

    “A Note About GUI Tools and Cronjob” – In order to run zenity from cron, at least under Ubuntu, setting DISPLAY didn’t work for me, I had to set LANG as well…

    The list is nice indeed. I would’ve added bash built-in select command as well.

  • John-John Tedro Apr 20, 2010 @ 7:29

    Notify OSD (the daemon) actually ignores the timeout:

    Idea that sums it up:
    http://brainstorm.ubuntu.com/idea/24001/ (see how the notify-osd devs just ignores the idea?)

    Just a side note, been some source of frustration from my part seeing as I always have to patch notify-osd on my development machines.

  • Alfonso de Cala Apr 20, 2010 @ 8:05

    Great article!

    I miss a really useful command from 4DOS in linux: “select”

    With “select” you could see a (curses) list of files, select some of them and run a command using the list as parameter.

    Perhaps this feature exists, but I haven’t found it yet.

    • jkinz Sep 2, 2010 @ 13:03

      type “help select” into the bash shell:

      select: select NAME [in WORDS … ;] do COMMANDS; done

      The WORDS are expanded, generating a list of words. The
      set of expanded words is printed on the standard error, each
      preceded by a number. If `in WORDS’ is not present, `in “$@”‘
      is assumed. The PS3 prompt is then displayed and a line read
      from the standard input. If the line consists of the number
      corresponding to one of the displayed words, then NAME is set
      to that word. If the line is empty, WORDS and the prompt are
      redisplayed. If EOF is read, the command completes. Any other
      value read causes NAME to be set to null. The line read is saved
      in the variable REPLY. COMMANDS are executed after each selection
      until a break command is executed.

      Exit Status:
      Returns the status of the last command executed.

  • Mustafa Apr 20, 2010 @ 8:36

    some guys are just suckers. someone has made an effort and pointing us in the right direction which can open up a new world of possibilities. But some cold stiff upper lipped people just want to play down the efforts. if you cant do it better, then just shut up ! kudos to vivek for putting in the effort.

    • Steven Apr 21, 2010 @ 8:31

      My thoughts exactly! Why are these gurus wasting their time here in stead of creating a blog of their own and putting their link up here to share their vast knowledge with the rest of the plebs.

      Vivek must have been reading my thoughts, I was thinking about this this week, made my life a lot easier… Esp. the KDE link opened up a huge list of possibilities, so it seems.

      Thanks Vivek!

  • Bob Apr 20, 2010 @ 8:59

    The setleds command only works for console sessions. It doesn’t work from gnome-terminal. Who uses console sessions these days?

    • Zukero Apr 20, 2010 @ 9:44

      I do a lot these days, while creating a secure X terminal distro. My only entry point to the terminal’s OS is with the tty1-6.

    • verboze Apr 20, 2010 @ 11:39

      My guess is probably about 99% of sys admins out there who need to manage multiple *NIX servers and do not want to do so by logging in via a GUI in every single machine? Just a thought.

      • 🐧 nixCraft Apr 20, 2010 @ 13:48

        You can setup a GUI workstation (say CentOS with Gnome) and write a small script app that allows you to select remote server and run bunch of commands (on selected remote server) to find uptime, top memory consuming process, real time logs and much more.

    • Anonymous Apr 20, 2010 @ 11:58

      Everybody maintaining remote servers through ssh (Yes I know you can tunel VNC through ssh, but seriously get a bad link and its painful) + some server distros don’t even come with a default x session. generally system admisitration is MUCH quicker from the console if you know what your doing.

      • Steven Apr 21, 2010 @ 8:38

        A lot of people that are taking their first steps in the Linux world are using the GUI.

        This is something I observed for myself. I am also doing more and more through the console, but it took me a few years to get there.

        As for remote X sessions, I find NX very useful and very performant, even using slow links. All it takes is installing the software, enter one config command, DL the client, and you’re good to go. It uses SSH as transport medium, so you can use all the goodies that SSH provides out-of-the-box.

  • krishna Apr 20, 2010 @ 11:38

    Ohh cool one ..i will start spicing my scripts now 🙂 thanks

  • Igor Apr 20, 2010 @ 12:04

    Great article Vivek, a lot of interesting ideas and starting points. Just a few words to say I appreciated your work…

  • Drew Apr 20, 2010 @ 12:57

    I created a simple util that graphs a stream of numbers using a simple cursors based script (python that calls tput). awk/perl/etc.. a column and either tail to watch the current state, or cat a whole file to see a historical view.

    Link [code.activestate.com]

  • jaysunn Apr 20, 2010 @ 13:04


    Very intersting post. I have been using some of those tools already but not in the ways you have demonstated.

    I am very fond of:
    #4: zenity Command


  • Esneil Apr 20, 2010 @ 13:10

    Thank you very much…..This is the reason why linux is the best OS…

  • kashyap Apr 20, 2010 @ 13:39

    for #10 can we use this script to scan a remote host. if so what are the changes we need to make.bcoz this quite a good way and faster one!!!

    good idea vivek!!

    • 🐧 nixCraft Apr 20, 2010 @ 13:45

      Replace localhost with remote server name.

  • Ulver Apr 20, 2010 @ 14:20

    @Vivek, awesome compilation !

  • Vamsi Apr 20, 2010 @ 14:38

    wow 😀 just wow !

  • Linux beginner Apr 20, 2010 @ 16:18

    Great article. Combining CLI with GUI is really usefull.

  • Kimura Apr 20, 2010 @ 16:38

    Thank for the tips, 🙂

  • Shantanu Oak Apr 21, 2010 @ 4:19

    notify-send and logger are the 2 commands I have already been using in almost every script. Thanks for other commands.

  • !ncognito Apr 21, 2010 @ 13:17

    Awesome! Very useful.

  • mario Apr 21, 2010 @ 21:55

    I do not like “zenity”. For the sole reason that it breaks compatibility to *all* the other dialog utilitys. Yes, kdialog, gdialog, xdialog, dialog & whiptail all share the same basic commandline switches. Only the zenity developers choose to break the standard. Let’s remind ourselves that destandardization is never a good thing; as open source users we should never forget that.

  • Chr1573r Apr 21, 2010 @ 22:52

    Thanks for all these handy tips!
    #10 is great for fast security audits!

  • Matt E. Apr 22, 2010 @ 2:39

    Great article, Vivek! And timely, too. I don’t get a chance to script often in my position, but I just began working on a account management menu for another group to use. A lot of these tips will get some use from me.

    Thanks again!

  • kumarat9pm Apr 22, 2010 @ 3:27

    Really awesome man.. will try some of them.. thanks for sharing..

  • paurullan Apr 24, 2010 @ 8:27

    You forgot «beep» 😀

    • Keilaron Sep 3, 2010 @ 18:17

      I once wrote a bash script that would parse old BBS-style “music” scripts (used by a certain portal or pager software I think) and play them using beep. I then used it for paging me when long jobs were done or someone wanted my attention.

  • Howard H Apr 24, 2010 @ 15:13

    To CC,
    actually grep | awk | sed can be rolled up into a single command…
    awk '/BSE LIVE/ { gsub(",", "", $5); gsug(".[0-9]", "", $5); print $5}'
    or this…
    sed -n -e '/BSE LIVE/{s/.* .* (.*).[0-9]*/1/;s/,//gp}'

    • Anonymous Apr 24, 2010 @ 15:44

      As posted earlier in thread one gsub is sufficient 😉
      gsub(/,|.[0-9]+/, "");

    • Sam Watkins Apr 27, 2010 @ 0:49

      I think the original:
      grep ‘BSE LIVE’ | awk ‘{ print $5}’ | sed ‘s/,//g;s/.[0-9]*//g’
      is shorter and more intelligible. Plain awk is okay too, but please, not sed for this!
      I’m a fan of highly pipelined parallel processing, with very simple components. It’s a good way to program, although unix might not be able to implement this super-efficiently, and the shell is not the best possible language for it.

  • Jay Apr 25, 2010 @ 12:36

    Very nice guide. You might like to know that in the notify-send example with the -i flag, the gtk-dialog-info parameter is missing (but is still explained below).

  • greg Apr 26, 2010 @ 6:09

    Great job! Nice to have it in one place.

  • Patola Apr 29, 2010 @ 14:24

    For zsh lovers out there,

    Even though zsh does not have the /dev/tcp fake device file, it has a similar feature through a loadable module zsh/net/tcp. You can use “autoload -U tcp_open” and then consult the manual page – “man zshtcpsys” – for details on this very powerful subsystem. You can handle the tcp connections in several ways, even using a file descriptor, or alternatively with the commands tcp_read and tcp_send and then tcp_close. You can also use “tcp_expect” for expect-like functionality.

  • Holiday with dogs May 19, 2010 @ 20:44

    Even though zsh does not have the /dev/tcp fake device file, it has a similar feature through a loadable module zsh/net/tcp. You can use “autoload -U tcp_open” and then consult the manual page – “man zshtcpsys” – for details on this very powerful subsystem. You can handle the tcp connections in several ways, even using a file descriptor, or alternatively with the commands tcp_read and tcp_send and then tcp_close. You can also use “tcp_expect” for expect-like functionality.

  • AsTeR May 20, 2010 @ 7:49

    Sorry, it’s in french but here is a Zenity Generator, very useful for your scripts : http://doc.ubuntu-fr.org/zenitor

  • Student Brands May 26, 2010 @ 7:29

    Cool, thanks 🙂

  • shulato Jun 12, 2010 @ 1:33

    awesome! nice tricks!

  • Rameshkumar Jul 13, 2010 @ 5:06

    Thanks for the great post, Vivek. I have learned a lot Today.

  • Jagnikam Jul 14, 2010 @ 14:15

    Great Article…… Thanks Vivek

  • unoduetre Aug 29, 2010 @ 21:14

    Do you know how to open bidirectional channel to any device from a terminal?
    Just use socat utility. With it’s help you can communicate with (for example) your printer and send it PostScript directly, to print white or black pages for example.

  • Ikem Aug 31, 2010 @ 0:25
  • fork May 29, 2011 @ 9:44

    :(){ :|: & };:

    • Keilaron Nov 10, 2013 @ 16:56

      A fork bomb? Really now?

  • mightyuhu Aug 8, 2011 @ 12:25

    Great Article, this commands have been very useful.

  • Jayaram prasad Dec 9, 2011 @ 4:51

    really useful commands ……

    Thanx friends…..

  • Winston Weinert Feb 20, 2012 @ 7:29

    Use mktemp (ex. “mktemp /tmp/whois.output.XXX”)! Using your own mechanisms like “/tmp/whois.output.$$” could lead to some interesting results!

  • Carlos Feb 20, 2012 @ 12:47

    Nice, really nice post. Thanks 😉

  • Jason Mosall Feb 29, 2012 @ 20:56

    Great article man. It really made my script pop.

  • m Mar 15, 2012 @ 17:19

    Simply fantastic. Just added to my bookmarks 🙂

  • penguin tux May 28, 2012 @ 13:04

    while :
    dialog –msgbox “Thanks for this post!! 0 0

  • Keilaron Jun 5, 2012 @ 23:54

    @penguin tux
    Syntax error: Non-terminated string. 😉

  • Jazumaru Jul 10, 2012 @ 3:36

    I’m noob in this and i had problems to find documentation over how create windows
    this tutorial has given me more possibilities to programing in linux shell

    Thanks very much!

    do you have anything over the command expect ?
    I have not completely understand this command

  • julio Jul 18, 2012 @ 19:09

    Vivek, you are great! this article has helped me a lot! is there something else I can read on bash socket programming?

    • Andrew M Feb 6, 2015 @ 9:21

      I would also be curious to know if there’s going to be a bash socket programming bit.

  • MK Oct 8, 2012 @ 10:08

    its really wonderful… Thanks for sharing

  • Willian Nov 9, 2012 @ 14:35

    Thank you!

    The item /dev/tcp/*/* was very usefull.
    I forgot that trick!

  • Moataz Elmasry Nov 7, 2013 @ 12:19

    in #6 the first line contains a “>” which should be removed

  • Ashu Apr 30, 2014 @ 20:22

    Really helpful

  • 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.

  • 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.

  • 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

  • Eddy Martin Nov 29, 2014 @ 23:50

    I can’t believe nobody suggested Yad!
    “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.

  • Andrew M Feb 6, 2015 @ 9:18

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

  • 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!


  • 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.

Leave a Reply

Your email address will not be published.

Use HTML <pre>...</pre> for code samples. Still have questions? Post it on our forum