Zenity is a very useful utility which let us create graphical user interfaces for our shell scripts. Several widgets exists, and can be used by invoking the program with the respective options. The widgets are based on the GTK
toolkit, and return the result of the user interaction either on the standard output or as a return code.
In this tutorial you will learn:
- What are the general zenity options
- What are the some of the most useful available widgets and how to use them
Software Requirements and Conventions Used
Category | Requirements, Conventions or Software Version Used |
---|---|
System | Distribution-independent |
Software | The zenity utility |
Other | Familiarity with the shell (bash in this case) and concepts like subshell and exit codes |
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
The zenity
package is included in the repositories of all the major linux distributions, and it may be already installed if you are using the GNOME
desktop environment. To install it we can use our favorite distribution package manager, in Fedora
, for example, we can use dnf
:
$ sudo dnf install zenity
When using Debian and debian-based distributions like Ubuntu, we can use the apt-get command:
$ sudo apt-get install zenity
Zenity is already included in the Archlinux extra
repository, therefore we can install it via pacman
:
$ sudo pacman -S zenity
Generic options
Before we start to see some of the most useful widgets provided by zenity
, we should mention some of the available generic options we can use to change the program behavior.
We call them generic because they can be applied independently of the chosen widget: --title
, --widow-icon
, --width
, --height
and --timeout
.
First of all we have the --title
option: we can use it to specify a title for the dialogue window. Similarly, the --window-icon
option let us specify an icon that will be used as the icon for the window, and will be visible, for example, in the taskbar. To display an icon in the widget, instead, we can use the --icon-name
option and provide one of the allowed icon names (here is the complete list) as argument. To use the stock icons provided in the error, info, question, or warning dialogues, for example, we can specify respectively: dialog-error
, dialog-info
, dialog-question
or dialog-warning
.
The --width
and --height
options are pretty self-explanatory: they let us define the geometry of our dialogue window.
Finally, by using the --timeout
option we can set a timeout in seconds for the dialogue: after the specified amount of time, it will be automatically closed.
The available widgets
There are several widget we can use thanks to zenity: each of them has a specific purpose. Let’s see some of them.
The calendar widget
The calendar widget will display a calendar and let the user pick a date, by selecting the month, day and year. The selected values will be returned on the standard output
. To launch the widget calendar, all we have to is to invoke zenity, with the --calendar
option:
$ zenity --calendar
We can use a series of option to fine-tune the behavior of the widget, for example, by using --day
, --month
, --year
and providing an INT
as value, we can set, respectively, the default day, month and year that will be displayed in the widget. To specify a specific format in which the selected date should be returned, we can use the --date
option and specify the pattern in the strftime
style.
The entry widget
The entry widget is really useful when we need to ask the user for some text. Say for example we need to ask the user to enter its name; we can run the following command:
$ zenity --entry --title "Name request" --text "Please enter your name:"
Here we used the --title
and --entry-text
options to customize, respectively, the title and the label that for the widget. Once we run the command above, the widget will appear:
The text entered by the user will be return on the standard output.
File selection widget
The file selection widget let us display a nice graphical interface to let the user select one or more files. Just as we did in the previous examples, we can use a series of options to modify the behavior and appearance of the dialogue. One of the most important one is --filename
which can be used to set the file/directory that will be selected by default. Here is a quick overview of the options and the functionalities they provide:
Option | Function |
---|---|
–filename | Set the default directory/file that will be selected in the widget |
–multiple | Enable the ability to select multiple files at once |
–file-filter | Specify a filter for filenames |
–directory | Restrict the selection to directories |
–save | Run the widget in “save” mode. |
–confirm-overwrite | Ask the user for confirmation when overwriting an existing file |
–separator | Specify a separator that will be used to separate paths when multiple files are selected |
Let’s see an example of the widget use. Say we want to let the user select multiple files, and we want the content of the user $HOME
directory to be displayed in the widget when it is opened. All we have to do is to run the following command:
$ zenity --file-selection --multiple --filename "${HOME}/"
You can notice that we provided a trailing /
to the path: this way the content of the directory is displayed, instead of the directory itself. Here is our widget:
Once we click on the “ok” button, the absolute path of the selected file(s) will be returned on the standard output, separated by a character, which be default is |
:
/home/egdoc/Downloads/a.txt|/home/egdoc/Downloads/b.txt
We can easily change the separator, providing the character we want to use as the argument of the –separator option.
If we open the dialogue in save mode
, the user will be asked to provide the name of the file he wants to save. If the file exists and we provided the --confirm-overwrite
option, he will be prompted to confirm he wants to overwrite it:
$ zenity --file-selection --save --confirm-overwrite --filename "${HOME}/"
The chosen path will be returned to the standard output, and we will be free to use it in our script.
The progress widget
Another interesting widget is the progress one: we can launch it using by invoking zenity with the --progress
option. We can use it, for example, to show the progress of long running operations. Here are some of the most useful options we can use with the widget:
Option | Function |
---|---|
–percentage | Sets the initial percentage value of the progress bar |
–auto-close | Automatically close the dialogue when the progress is completed |
–auto-kill | Kill the parent process if the dialogue is closed with the cancel button |
–no-cancel | Don’t display the cancel button |
Here is an example of how we can use the widget within a bash script:
#!/bin/bash
#
# Dummy script to demonstrate the zenity progress widget!
(
echo 25
echo "# Setting up..."
sleep 2
echo 30
echo "# Reading files..."
sleep 2
echo 70
echo "# Creating content..."
sleep 1
echo 100
echo "# Done!"
) | zenity --title "Progress bar example" --progress --auto-kill
The script above doesn’t actually perform any operation, but it’s useful to understand how the widget works. There are two main things that should be noticed in the code: first of all, the commands to be executed are wrapped between parenthesis, therefore are executed in a subshell
: this is necessary for the widget to work correctly; second, when we echo a line starting with a number, this will be interpreted as the percentage of the progress bar.
In the same way, when we echo a line which starts with the #
character, it will be used as the text to be displayed in the widget. Here is a short video of the script in action:
Info, warning and error widgets
To display info, warning or error messages, we can use zenity with the --info
, --warning
and --error
options, respectively. In this case we use the --text
option to specify the message. Here is an example of a notification:
$ zenity --info --width=400 --height=200 --text "This is a notification!"
Using the warning widget, is just as easy:
$ zenity --warning --width=400 --height=200 --text "This is a warning!"
This, instead is an example of an error message:
$ zenity --error --width=400 --height=200 --text "This is an error!"
The question widget
To ask the user a question and get its answer we can use the question
widget, invoking zenity with the --question
option. We specify the question using the --text
option, and define the labels of the ‘ok’ and ‘cancel’ buttons, using respectively the --ok-label
and --cancel-label
options. Here is an example:
$ zenity --question --text "Are you sure you want to quit?" --no-wrap --ok-label "Yes" --cancel-label "No"
In this case, we also used the --no-wrap
option, to avoid text wrapping in the widget. The result of the user choice will not be displayed on the standard output; instead, the command will set its exit code
accordingly, so it will return 0
if the user clicks on the ‘ok’ button, and 1
if he clicks on the ‘cancel’ one or closes the window (this may seems counter-intuitive, but remember than an exit code of 0 means that a command was executed with success in the shell).
The password widget
This is the widget we should use when we want the user to enter a password or any sensitive information: the text he enters is masked by bullets:
While the text entered from the user is masked, the value returned by the widget will be clearly visible on the standard output.
The color selection widget
This is another nice widget. By using it, we can make the user choose a color from a palette. To run it, we use zenity with the --color-selection
option. We can specify the initially selected color by using --color
and provide the color as argument. Here is an example:
Optionally, we can display the color palette instead, with the --show-palette
option:
$ zenity --color-selection --color red --show-palette
The color selected by the user will be returned in rgb
notation on the standard output. For example when selecting the color red, the following will be returned:
rgb(255,0,0)
The list widget
The next widget we will take a look at, is the list widget. With it, it’s possible to create a multi-column dialogue, and optionally let the user select one or multiple options via checkboxes or radio buttons. To make zenity display this type of dialogue we use the --list
option and define the columns and their contents; if we omit them the command will fail:
$ zenity --list
No column titles specified for List dialog.
To define a column header we use the --column
option and provide a string as argument. We repeat the command for each column we want to create:
$ zenity --list --column Selection --column Distribution
With the command above we created two columns, with the “Selection” and “Distribution” headers. Now we will provide the user with a series of row, each of them representing a linux distribution. In the first column of each row we will place a checkbox to let the user select the corresponding entry:
$ zenity --list --column Selection --column Distribution FALSE Debian TRUE Fedora -radiolist
Each string we provide after the columns definition are associated with the columns, depending on their order of appearance. As you can see we created two rows. In the first column of each row we provided a value: we used FALSE
so that the corresponding checkbox or radio button are not selected when the widget is displayed, and TRUE
to set the input as flagged by default. Here is the generated widget:
When we click on the “ok” button, and perform our selection, the value associated with the row will be reported on the standard output. If we want to let the user select multiple rows we can use the --checklist
option: the | character will be used to separated the selected values.
Conclusions
In this tutorial we learned to know zenity
, an utility that let us use graphical dialogues in our shell scripts. We saw what are the generic options we can use with all the widgets, like --width
and --height
, and we learned to use some of the most useful widgets we can generate with the program. To learn more about zenity
you can consult its manpage!