Improve Bash Shell Scripts Using Dialog
http://www.linuxjournal.com/article/2460
The "dialog" command offers an easy way to draw text-mode colored windows.
These windows can contain text boxes, message boxes or different kinds of menus.
There are even ways of using input from the user to modify the script behaviour.
The current version of the dialog program is cdialog-0.9 and can be freely
downloaded from Sunsite's /pub/Linux/utils/shell directory. Dialog uses the
ncurses library, so it too must be installed. Some Linux distributions such as
Slackware include the dialog program because of utilities which rely on it
(setup, pkgtool). By the way, these utilities are great examples of using
dialog.
cdialog:
dependencies: ncurses
Debian/Ubuntu Install:
apt-get install dialog
Basic Usage:
#!/bin/sh
dialog --title "Dialog message box" --msgbox "\n Hello world !" 6 25
--------------------------------------------------------------------------------
List Directory Contents Script (--inputbox)
#!/bin/sh
# list the contents of a dir
dialog --title "Dialog input box" --inputbox "Input directory:" 8 40 `pwd` 2>/tmp/dialog.ans
if [ $? = 1 ]; then
rm -f /tmp/dialog.ans
clear
exit 0
fi
ANS=`cat /tmp/dialog.ans`
ls -al $ANS > /tmp/dialog.ans
dialog --no-shadow --title "listing of"$ANS --textbox /tmp/dialog.ans 25 78
clear
rm -f /tmp/dialog.ans
exit 0
The text box allows navigating with the arrow keys or home/end/pgup/pgdown keys
and even has simple searching facilities. Typing / while the text box is
displayed causes another window to appear, which prompts the user for a string
to be searched forward in the file. Typing ? performs reverse searching, just
as for the less pager. The first line containing the string is displayed at the
top of the text box.
What if the directory name is wrong? The shell script will not complain, but
will show an empty text box since there are no files in a nonexistent directory.
To solve this problem, a check is made to see if the specified directory exists.
Actually, the ls command returns an exit status of 0 if the directory exists,
and 1 if it doesn't. Thus, the script can be modified by adding these lines:
ls -al $ANS > /tmp/dialog.ans 2>/dev/null
if [ $? = 1 ]; then
clear
echo no such directory
exit 1
fi
First, the ls line is changed, redirecting standard error to /dev/null. This
means no error messages from ls will appear on the screen. Then, if the exit
status ($?) is 1, the script will exit with an error message.
--------------------------------------------------------------------------------
This script can be made even more useful by allowing the user to examine more
directories before the script exits.
#!/bin/sh
# Lists the contents of a directory
while [ 0 ]; do
dialog --title "Dialog input box" --inputbox "Input directory or \n press to exit" 9 40 `pwd` 2>/tmp/dialog.ans
if [ $? = 1 ]; then
clear
rm -f /tmp/dialog.ans # don't litter !
exit 0
fi
ANS=`cat /tmp/dialog.ans`
ls -al $ANS > /tmp/dialog.ans 2>/dev/null
if [ $? = 1 ]; then
dialog --title "Error" --msgbox "no such directory" 5 40
continue
fi
dialog --no-shadow --title "listing of "$ANS -textbox /tmp/dialog.ans 25 78
done
A few changes have been made. First, the entire script has been included in a
while-do loop which is always true. This allows it to run more than once. Now
the only way of exiting the script (besides typing ctrl-c) is by selecting the
Cancel button in the dialog input box. The second change is the introduction of
a message box which will be displayed when the ls command returns an exit status
of 1. The command continue deserves a special comment. Its meaning is to skip
the current iteration of the while loop (i.e., the part which shows the text
box) and start a new one. Thus, after the error message, the user will again
see the input box, prompting for another directory name.
--------------------------------------------------------------------------------
The menu box is produced by running dialog with the --menu option with the
format:
dialog --menu
tag2 item2...
This option displays a box with two buttons (OK and Cancel) and a menu
consisting of one or more lines. Each line has a "tag" (a number or word) and
an "item", which is usually text describing the menu entry. When a user selects
an item and then clicks on the OK button, the corresponding tag is printed on
STDERR. Also, the exit status of dialog is 0 for the OK button being selected
and 1 for the Cancel button.
Menu boxes are useful in that they allow the user to choose from several fixed
alternatives. For example, when producing a LaTeX document, three steps must be
taken: editing the source file with a word processor, compiling it with LaTeX
and viewing the resulting .dvi file. It is easy to build a shell script to do
these steps. (See Listing 3 which assumes the text editor is jed, the .dvi file
viewer is dvisvga and both are in the path.) The complete script is again
included in a “while” loop for the purpose of making it work more than one time.
The only way to exit this script is by selecting the "Cancel" button in the
first menu box. Otherwise, the user has to choose between three alternatives:
Edit a text file.
Compile a LaTeX file.
View a .dvi file.
The answer is stored in the file /tmp/ans and retrieved in the variable R. If
the user chooses to edit a file, a new dialog box appears. It is an input box
and prompts for a file name. The answer goes into the variable F. Then the
script checks whether the file exists and runs the command:
jed $F # where $F is the name of the file
If the file does not exist, it is either a new one or a typing error. To
distinguish between these two possibilities, a yes/no dialog box is provided.
The general format of such a box is:
--yesno
The box has two buttons, YES and NO. The text is usually a question, which the
user answers by selecting a button. If YES, $? (the exit status of the dialog
command) is 0; if NO, $? is 1.
In Listing 3, if the answer is YES, the text editor is invoked; if NO, the
script returns to the main menu through the continue command. The other two
choices work in the same way, the only difference being the commands for
processing the file with LaTeX or for viewing the resulting DVI file:
latex $F
dvisvga $F
Several other dialog boxes are available, such as the checklist or the
radiolist; however, their use is quite similar to that of the menu box.
--------------------------------------------------------------------------------
The following is an example of the --guage dialog box. This is used to
graphically display a percentage. The syntax is:
dialog --guage
Once started, the guage box keeps reading percent values from STDIN until an EOF
is reached and changes the display accordingly. Here is a simple (but not very
useful) guage script:
#!/bin/bash
{ for I in 10 20 30 40 50 60 70 80 90 80 70 60 50 40 30 20 10 0; do
echo $I
sleep 1
done
echo;
} | dialog --guage "A guage demo" 6 70 0
Copy this into a file, give it execute permission, run and enjoy! The first
part of the script (included in braces) is a group command. Every second it
sends one of the listed values to the guage dialog box. The final echo command
is used to terminate the dialog box.
--------------------------------------------------------------------------------
#!/bin/sh
#script for editing, proccesing and viewing LaTeX documents
while [ 0 ]; do
dialog --title "Dialog menu box" --menu "Choose one of the following or press to exit" 11 40 3 \
"1" "Edit a text file" \
"2" "Compile a latex file" \
"3" "View a .dvi file" 2>/tmp/ans
if [ $? = 1 ]; then
rm -f /tmp/ans
clear
exit 0
fi
R="`cat /tmp/ans`"
if [ $R = "1" ]; then
dialog --title "Dialog input box" --inputbox "Please input file name:" 8 40 $F 2>/tmp/ans
if [ $? = 1 ]; then
continue
fi
F="`cat /tmp/ans`"
if [ -f $F ]; then
jed $F
else # if the file does not exist...
dialog --title "Dialog yesno box" --yesno "\n Is this a new file ?" 6 40
if [ $? = 0 ]; then
jed $F
else
continue
fi
fi
elif [ $R = "2" ]; then
dialog --title "Choose file" --inputbox "Please input file name:" 8 40 $F 2>/tmp/ans
if [ $? = 1 ]; then
continue
fi
F="`cat /tmp/ans`"
if [ -e $F ]; then
clear
latex $F
else # if the file does not exist...
dialog --title "Dialog message box" --msgbox "\n File not found" 6 30
continue
fi
elif [ $R = "3" ]; then
dialog --title "Dialog input box" --inputbox "Please input file name:" 8 40 $F 2>/tmp/ans
if [ $? = 1 ]; then
continue
fi
F="`cat /tmp/ans`"
if [ -f $F ]; then
clear
tmview $F
else # File not found...
dialog --title "Dialog message box" --msgbox "\n File not found" 6 30
continue
fi
fi
done
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
user@vmwarex[~] $ dialog
cdialog (ComeOn Dialog!) version 1.1-20070604
Copyright 2000-2006,2007 Thomas E. Dickey
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* Display dialog boxes from shell scripts *
Usage: dialog { --and-widget }
where options are "common" options, followed by "box" options
Special options:
[--create-rc "file"]
Common options:
[--ascii-lines] [--aspect ] [--backtitle ]
[--begin ] [--cancel-label ] [--clear] [--colors]
[--cr-wrap] [--default-item ] [--defaultno] [--exit-label ]
[--extra-button] [--extra-label ] [--help-button]
[--help-label ] [--help-status] [--ignore] [--input-fd ]
[--insecure] [--item-help] [--keep-tite] [--keep-window]
[--max-input ] [--no-cancel] [--no-collapse] [--no-kill]
[--no-label ] [--no-lines] [--no-shadow] [--ok-label ]
[--output-fd ] [--print-maxsize] [--print-size] [--print-version]
[--separate-output] [--separate-widget ] [--shadow]
[--single-quoted] [--size-err] [--sleep ] [--stderr] [--stdout]
[--tab-correct] [--tab-len ] [--timeout ] [--title ]
[--trace ] [--trim] [--version] [--visit-items]
[--yes-label ]
Box options:
--calendar
--checklist ...
--dselect
--editbox
--form