Originally published November 27, 2017 @ 10:49 pm
Whiptail is a newt-based utility allowing to build pseudo-graphical dialog boxes from shell scripts. Dialog uses ncurses and is similar to whiptail but has more options and, consequently, a bit harder to use. I find both useful when a user needs to be guided through a complex set of variables and to minimize fat-fingering.
The best to understand how to use dialog and whiptail (and sometimes you would want to use both of them in the same script) is by looking at some example. In this first example we’re prompting the user for database connection information to build the ${MYSQL} connection string:
get_db_host() {
db_host=$(whiptail --inputbox "Database host:" 8 78 "localhost" --title "Query Dialog" 3>&1 1>&2 2>&3)
db_port=$(whiptail --inputbox "Database port:" 8 78 "3336" --title "Query Dialog" 3>&1 1>&2 2>&3)
db_user=$(whiptail --inputbox "Database user:" 8 78 "sqlman" --title "Query Dialog" 3>&1 1>&2 2>&3)
db_pass=$(whiptail --passwordbox "Database pass:" 8 78 "dbs1721" --title "Query Dialog" 3>&1 1>&2 2>&3)
MYSQL="/usr/bin/mysql --batch --skip-column-names --max_allowed_packet=100M -h${db_host} --port=${db_port} -u${db_user} -p${db_pass} -e"
}
The next example connects to the database to populate a whiptail radio checklist with the names of available schemas. The second function connects to the selected database to get a list of tables and build another radio checklist. This is a good example of how to build dynamic menus.
get_db_name() {
db_name=$(whiptail --title "Available Databases" --radiolist "Selects a database:" 30 78 20 \
`$MYSQL "show databases;" | sed 's/$/ DB OFF/g'` 3>&1 1>&2 2>&3)
MYSQL="/usr/bin/mysql --batch --skip-column-names --max_allowed_packet=100M -h${db_host} --port=${db_port} -u${db_user} -p${db_pass} ${db_name} -e"
}
get_tbl_name() {
tbl_name=$(whiptail --title "Available Tables in ${db_name}" --radiolist "Selects a table:" 30 78 20 \
`$MYSQL "show tables;" | sed 's/$/ TBL OFF/g'` 3>&1 1>&2 2>&3)
}
The whiptail utility has an unfortunate limitation: it can only ask you one question at a time. This can get tedious and distracting. The following example uses dialog to present you with three questions and set variables var1 through var3. The dialog can’t assign each response to an individual variable. You would need to parse the output as illustrated below.
dialog_do() {
# Clear variables var1 - var3
unset var{1..3}
# Set default values
var1="default value 1"
var2="default value 2"
var3="default value 3"
# Launch dialog and gather user input
exec 3>&1
dialog_values="$(dialog --ok-label "Submit" \
--clear \
--output-separator : \
--backtitle "Setting variables var1 - var7" \
--title "Some questions for you" \
--form "Answer this" \
20 60 0 \
"Enter var1:" 1 1 "${var1}" 1 16 25 0 \
"Enter var2:" 2 1 "${var2}" 2 16 25 0 \
"Enter var3:" 3 1 "${var3}" 3 16 25 0 \
2>&1 1>&3)"
exec 3>&-
clear
# Now we parse the input assigned to colon-separated ${dialog_values} and set
# individual variables
for i in {1..3}; do
eval "$(echo var${i})"="\"$(awk -F: -v i="${i}" '{print $i}' <<<${dialog_values})\""
done
# And this is just to show that the variables have been set
for i in {1..3}; do
eval echo $(echo $`eval echo "var${i}"`)
done
}
And a few simple whiptail dialog boxes that may come in handy in many scripts. This is a simple yes/no dialog:
if (whiptail --title "Continue/Exit" --yes-button "Continue" --no-button "Exit" --yesno "Proceed with the build?" 20 60); then echo "Continuing" fi
Here’s a simple message box. For some visual interest I added output of an array containing output of the ps command:
IFS=$'\n'; a=($(ps -eLfw)); unset IFS
whiptail --title "Simple message box" --msgbox "This is first line\n\nThis is second line\n\n$(for ((i = 0; i < ${#a[@]}; i++)) ; do echo "${a[$i]}" ; done | grep httpd)" 30 100
This is another message box designed to hold a bit more content:
whiptail --title "Scrollbox" --scrolltext --msgbox "$(tail -1000 /var/log/messages)" 30 100

Experienced Unix/Linux System Administrator with 20-year background in Systems Analysis, Problem Resolution and Engineering Application Support in a large distributed Unix and Windows server environment. Strong problem determination skills. Good knowledge of networking, remote diagnostic techniques, firewalls and network security. Extensive experience with engineering application and database servers, high-availability systems, high-performance computing clusters, and process automation.




















