In this tutorial we will learn the basics of the dialog utility, in order to use ncurses
widget in our shell scripts. We will see how to install dialog in the most used Linux distributions, some of the common options we can use to alter the behavior of dialog, how to use some widgets; among the others: inputbox
, checklist
, radiolist
and yesno
. Finally, we will see how to use the data obtained by the widget processing.
In this tutorial you will learn:
- How to install the dialog utility on Linux
- What are the most relevant dialog options
- How to use the inputbox, checklist, radiolist, passwordbox, msbox, calendar and yesno widgets
- How to manage data derived from the widget processing
Software Requirements and Conventions Used
Category | Requirements, Conventions or Software Version Used |
---|---|
System | Distribution-independent |
Software | The dialog utility is needed to follow this tutorial |
Other | Familiarity with the command line interface and shell redirections |
Conventions | # – requires given linux commands to be executed with root privileges either directly as a root user or by use of sudo command$ – requires given linux commands to be executed as a regular non-privileged user |
Installation on Linux
The dialog
utility is available in all the major Linux distributions default repositories, therefore we can use our favorite package manager to install it. If we are using Fedora, for example, we can run:
$ sudo dnf install dialog
On Debian we can run:
$ sudo apt-get install dialog
The dialog
utility is also contained in the Archlinux core repository, so we can install it via pacman
:
$ sudo pacman -S dialog
Installing commands applies also to derivatives of the distributions mentioned above.
Common dialog options
We call this options “common” because they can be used independently of the type of widget we want to use. Here we will just see some of them, the ones which may be of immediate interest when we start using dialog
.
Settings a widget box title: the –title option
By using the --title
option we can specify a string which will be used as the widget title; it will be displayed at the top of the box. Here is an example:
$ dialog --title "Dialog title" --inputbox "Enter your name:" 0 0
Here is what is displayed as the result of the command above:
Combining widgets: the –and-widget option:
The --and-widget
option, can be used to “chain” more widgets, so that after we use the first, we are immediately prompted with the second. The chain is stopped when one of the dialogs returns a non-zero exist status. An example of its usage is:
$ dialog \ --inputbox "Enter your name:" 0 0 \ --and-widget --inputbox "Enter your age:" 0 0
Once we launch the command above, the first input widget used to prompt us for our name will be displayed. Once we confirm the input by clicking on the OK
button, the next widget will be displayed, and we will be prompted to input our age.
Clearing the screen with the –clear option
When we use the --and-widget
option the content created by one widget overrides that produced by the previous one. If the widgets don’t occupy the exact same screen space, the two contents would be mixed, and this would create a mess.
To avoid contents overlapping, we can use the --clear
option; when we do, the content of a widget is erased before the next widget is displayed: only the background color is preserved.
Setting the a button as highlighted by default: the –default-button option
Depending on the widget we are using, more than one button can be displayed onscreen and by default one of them is highlighted by default, determining the default action to be performed when the user presses enter.
We can override the
widget default by using the --default-button
option followed by the name of the button, one among ok
, yes
, cancel
, no
, help
or extra
.
This option can be really useful, for example, when prompting for confirmation before executing a potentially
dangerous action:
$ dialog --default-button "no" --inputbox "Enter your name:" 0 0
As you can see from the screenshot, we made so that the “no” button is selected by default, so that the user should explicitly select “yes” to confirm its choice.
Setting the default selected element in a list with –default-item
When we use a checklist or a menu widget, the first element in the list of the possible choices is selected by default. By using the --default-item
option and referencing an element, we can use it as an alternative default:
$ dialog --default-item 2 --checklist "Select:" 0 0 5 \ 1 "First element" off \ 2 "Second element" off \ 3 "Third element" off
As you can see, in the example above, we referenced the element by its tag
, 2 in this case (we will expand on this later).
Specifying a time delay after confirmation: the –sleep option
Sometimes we may want our application to wait for a certain number of seconds after processing a dialog box. To reach this behavior we can use the --sleep
option and provide the number of seconds to wait as a value:
$ dialog --sleep 3 --inputbox "Enter your name:" 0 0
As the result of the above command, after the inputbox
widget is displayed, and the user hits the ENTER
key, 3
seconds are waited before the next command in the calling script is performed.
Providing a choice timeout
In some cases we may want to give the user a maximum number of seconds to perform its choice. The dialog application provides the --timeout
option to obtain said behavior. The number of timeout seconds must be passed as the argument of the option. If after the specified amount of seconds provided the user doesn’t perform its choice, the application will exit with an error status:
$ dialog --timeout 3 --inputbox "Enter your name:" 0 0
Setting alternative labels for buttons
The dialog
utility provides a series of options to override the default label for buttons: we can use the --exit-label
, --extra-label
, --help-label
, --no-label
, --ok-label
, --yes-label
to change the labels of the “exit”, “extra”, “help”, “no”, “ok” and “yes” buttons, respectively.
Each of the aforementioned options take a string as argument, which is use as the button label. Here is an example of the option usage:
$ dialog --default-button "no" \ --no-label "I don't" \ --yes-label "I do" \ --yesno "Do you really want to format the partition?" 0 0
The above command will produce the following result:
Dialog widgets
Until now we saw some of the most useful dialog
“common” options. Now we will see how to use some of the available widgets in details. Before proceeding, we must specify the general syntax. When we launch a dialog we must always provide three parameters:
- The text to be displayed in the widget;
- The widget width;
- The widget height;
If we provide a value of 0
for width or height, the value of the corresponding attribute is set automatically.
The inputbox widget
The inputbox widget is used to prompt the user to respond to a question with a textual input. The text parameter is used to provide the question: if the string is longer than the dialog box, the latter will become scrollable. To use this widget we invoke dialog with the --inputbox
option:
On exit, the input provided by the user is displayed on dialog output, which by default is stderr
.
The checklist widget
We already saw how the checklist widget looks like in previous examples: in this type of widget a series of choices are provided to the user which can select one or more of them. To use this widget we must use the --checklist
option, and, in addition to the standard three parameters which must be passed to all widgets, we must provide also the list-height
and the choices to be displayed.
The line-height
parameter is used to set how many lines should be displayed at once: if the numbers of lines is less than the available choices, the menu will become scrollable. If we provide 0
as the value of line-height
the number of lines will correspond to the number of choices.
For each choice we must provide an identifier (tag), a name and a status which can be off
or on
. If the status is on
the choice will be checked by default. Once we confirm our choices the tags related to the entry we checked will be displayed on stderr
:
$ dialog --checklist "Select items:" 0 0 0 \ 1 "Choice number one" off \ 2 "Choice number two" on \ 3 "Choice number three" off \ 4 "Choice number four" on
With the command above we launched the menu with 4 options, and set options 2 and 4 checked by default. The output of the command is the following:
The radiolist widget
The radiolist widget is launched when dialog is invoked with the --radiolist
option. It works similarly to the checklist widget, with the difference that choices are mutually exclusive, so only one element can be selected. Here is how we use the widget:
$ dialog --radiolist "Select items:" 0 0 0 \ 1 "Choice number one" Off \ 2 "Choice number two" on \ 3 "Choice number three" off \ 4 "Choice number four" Off
Since the choices are mutually exclusive, only the first option set to On
will selected as a default.
Ask the user for a password using the passwordbox widget
The passwordbox widget is used to let prompt a user to enter a password. For security reasons, the text entered by the user is not displayed. This behavior can be modified by using the --insecure
option: if we do, the widget will display an asterisk for each letter of the password entered in the corresponding field.
We use the widget by launching dialog with the --passwordbox
option:
$ dialog --insecure --passwordbox "Enter your password:" 0 0
The output of the command above is:
Displaying a message with the msgbox widget
The usage of this widget is really simple: it is invoked by calling dialog with the --msgbox
option and displays a message which is the content of the text
parameter. A single OK
button is displayed:
$ dialog --msgbox "This is a very important message that should be read carefully!" 0 0
The calendar widget
We can use the calendar widget by invoking the dialog utility with the --calendar
option. The widget let us select a date by choosing month, day and year which are displayed in separate sections of the widget. It is possible to provide a default date by passing it as part of the command.
To start the widget with the “fifth day of May of the year 2020” as the default date, for example, we would run the following command:
$ dialog --calendar "Select a date:" 0 0 27 05 2020
It will produce the following output:
We can move between the widget sections using the TAB
key, and change parameters by using the arrow keys. Once we confirm the selection, it is displayed to stderr
in the format day/month/year; this can be modified by using the --date-format
option with a format compatible with strftime
specified as argument. To make the output in the format year/month/day, for example, we would run:
$ dialog --date-format %Y/%m/%d --calendar "Select a date" 0 0 27 05 2020
Prompt the user for confirmation: the yesno widget
We already encountered this widget: it let us prompt the user for confirmation. When using it, we specify the question to be asked via the text
parameter. Depending on the user choice an exit status is returned: 0
if the user confirms by clicking on the Yes
button, 1
otherwise.
To invoke this widget we must use the --yesno
option:
$ dialog --yesno "Do you confirm?" 0 0
Here is the widget:
Managing the output produced by a widget
By default, the output produced by a widget is displayed on stderr, so for example, to store the data obtained from a widget to a file, all we have to do is redirect stderr
to said file (if you are not familiar with redirections you may want to take a look at Introduction to bash shell redirections tutorial):
$ dialog --checklist "Select items:" 0 0 0 \ 1 "Choice number one" off \ 2 "Choice number two" on \ 3 "Choice number three" off \ 4 "Choice number four" on 2> choice.txt
Once the user confirms its choices, they will be written, space-separated into the choice.txt
file.
What if we want to store the selection directly into a variable? To accomplish the task we must use the --stdout
option, so that the output of the widget is displayed on stdin
instead of stderr
:
$ choices="$(dialog --stdout --checklist "Select items:" 0 0 0 \ 1 "Choice number one" off \ 2 "Choice number two" on \ 3 "Choice number three" off \ 4 "Choice number four" on)"
In the example above, the result of the widget processing, will be accessible via the choices
variable. Perhaps we may want to loop over them:
$ for choice in ${choices}; do echo "${choice}"; done 2 4
To manage the process of the yesno
widget we must behave differently. Said widget, as we already saw, doesn’t produce any output but changes the exit code of the command used to dislay it accordingly to the user choice. If the user confirms, and answers affirmatively to the question, the exit code is set to 0
, otherwise to 1
(this may seem odd, but remember that 0
means OK
while 1
is an exit status that means that a command was not succesfull). Knowing this we can write something like:
if dialog --yesno "Do you want to open an instance of gnome-terminal ?" 0 0; then clear gnome-terminal fi
Conclusions
In this tutorial we saw how we can use the dialog
application to use ncurses
widget in shell scripts. First we saw some common options which can be used independently of the widget type, than we took a look at some widgets specifically. There are many more widgets that can be used with dialog
: for a complete list I suggest you to take a look at the application manual.