Bash Shell Scripting/Whiptail
Whiptail is a program that allows shell scripts to display dialog boxes to the user for informational purposes, or to get input from the user in a friendly way. Whiptail is included by default on Debian.
- From the Linux Dictionary: whiptail is a "dialog" replacement using newt instead of ncurses.
- From its README: whiptail is designed to be drop-in compatible with dialog(1), but has fewer features: some dialog boxes are not implemented, such as tailbox, timebox, calendarbox, etc.
Try using dialog to replace whiptail if you don't have whiptail: alias whiptail='dialog'
Note that there are also other dialog-compatible programs like xdialog (Displays X11 Windows) and zenity (aka gdialog, displays Gtk Windows). Reading dialog's manual page should be helpful. Always read the man pages or --help
so you know in which way they're different from dialog.
Info box
editA simple type of dialog box in Whiptail is the info box. This shows a dialog box containing text to the user.
whiptail --title "Example Dialog" --infobox "This is an example of an info box." 8 78
In the example above, the value of --title is displayed at the top of the dialog box. The first argument to --infobox is the dialog box text which is shown beneath the title. The next two arguments specify the height and width of the dialog box. The width is set to 78 as most terminals will be at least 80 columns or more.
There is a bug that makes the Info Box not display on some shells. If this is the case you can set the terminal emulation to something different and it will work.
TERM=ansi whiptail --title "Example Dialog" --infobox "This is an example of an info box" 8 78
Message box
editA message box is very similar to an info box, except that it waits for the user to hit the OK button. Usage is similar to the info box:
whiptail --title "Example Dialog" --msgbox "This is an example of a message box. You must hit OK to continue." 8 78
Yes/no box
editThe simplest way to get input from the user is via a Yes/no box. This displays a dialog with two buttons labelled Yes and No.
# If you cannot understand this, read Bash_Shell_Scripting/Conditional_Expressions again.
if whiptail --title "Example Dialog" --yesno "This is an example of a yes/no box." 8 78; then
echo "User selected Yes, exit status was $?."
else
echo "User selected No, exit status was $?."
fi
Input box
editA way to get free-form input from the user is via an input box. This displays a dialog with two buttons labelled Ok and Cancel.
COLOR=$(whiptail --inputbox "What is your favorite Color?" 8 39 Blue --title "Example Dialog" 3>&1 1>&2 2>&3)
# A trick to swap stdout and stderr.
# Again, you can pack this inside if, but it seems really long for some 80-col terminal users.
exitstatus=$?
if [ $exitstatus = 0 ]; then
echo "User selected Ok and entered " $COLOR
else
echo "User selected Cancel."
fi
echo "(Exit status was $exitstatus)"
Text box
editA text box with contents of the given file inside. Add --scrolltext if the filename is longer than the window.
echo "Welcome to Bash $BASH_VERSION" > test_textbox
# filename height width
whiptail --textbox test_textbox 12 80
Password box
editA way to get a hidden password from the user is via a password box. This displays a dialog with two buttons labelled Ok and Cancel.
PASSWORD=$(whiptail --passwordbox "please enter your secret password" 8 78 --title "password dialog" 3>&1 1>&2 2>&3)
# A trick to swap stdout and stderr.
# Again, you can pack this inside if, but it seems really long for some 80-col terminal users.
exitstatus=$?
if [ $exitstatus == 0 ]; then
echo "User selected Ok and entered " $PASSWORD
else
echo "User selected Cancel."
fi
echo "(Exit status was $exitstatus)"
Menus
editWhenever you want to present a list of options to the user, whiptail has several dialog types to choose from.
A menu should be used when you want the user to select one option from a list, such as for navigating a program.
whiptail --title "Menu example" --menu "Choose an option" 25 78 16 \
"<-- Back" "Return to the main menu." \
"Add User" "Add a user to the system." \
"Modify User" "Modify an existing user." \
"List Users" "List all users on the system." \
"Add Group" "Add a user group to the system." \
"Modify Group" "Modify a group and its list of members." \
"List Groups" "List all groups on the system."
The values given to --menu are:
- The text describing the menu ("Choose an option")
- The height of the dialog (25)
- The width of the dialog (78)
- The height of the menu list (16)
The rest of the values are a list of menu options in the format tag item, where tag is the name of the option which is printed to stderr when selected, and item is the description of the menu option.
If you are presenting a very long menu and want to make best use of the available screen, you can calculate the best box size by.
eval `resize`
whiptail ... $LINES $COLUMNS $(( $LINES - 8 )) ...
Check list
editAt some point, you will want to present options to the user which would not be appropriate to place in a menu.
A check list allows a user to select one or more options from a list.
whiptail --title "Check list example" --checklist \
"Choose user's permissions" 20 78 4 \
"NET_OUTBOUND" "Allow connections to other hosts" ON \
"NET_INBOUND" "Allow connections from other hosts" OFF \
"LOCAL_MOUNT" "Allow mounting of local devices" OFF \
"REMOTE_MOUNT" "Allow mounting of remote devices" OFF
When the user confirms their selections, a list of the choices is printed to stderr.
Radio list
editA radio list is a dialog where the user can select one option from a list. The difference between a radio list and a menu is that the user selects an option (using the space bar in whiptail) and then confirms that choice by hitting OK.
whiptail --title "Radio list example" --radiolist \
"Choose user's permissions" 20 78 4 \
"NET_OUTBOUND" "Allow connections to other hosts" ON \
"NET_INBOUND" "Allow connections from other hosts" OFF \
"LOCAL_MOUNT" "Allow mounting of local devices" OFF \
"REMOTE_MOUNT" "Allow mounting of remote devices" OFF
Progress gauge
editSyntax: whiptail --gauge <text> <height> <width> [<percent>]
Also reads percent from stdin:
#!/bin/bash
{
for ((i = 0 ; i <= 100 ; i+=5)); do
sleep 0.1
echo $i
done
} | whiptail --gauge "Please wait while we are sleeping..." 6 50 0