How to use graphical widgets in bash scripts with zenity

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

Software Requirements and Linux Command Line Conventions
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.


calendar-widget

The calendar widget

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:


entry-widget

The entry widget

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:

Zenity file selection widget options
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:


file-selection-widget

The file selection 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!"


notification-widget

The notification widget

Using the warning widget, is just as easy:

$ zenity --warning --width=400 --height=200 --text "This is a warning!"


warning-widget

The warning widget

This, instead is an example of an error message:

$ zenity --error --width=400 --height=200 --text "This is an error!"


error-widget

The error widget

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"


question-widget

The question widget



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:


password-widget

The password widget

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:


color-widget-no-palette

The color selection widget

Optionally, we can display the color palette instead, with the --show-palette option:

$ zenity --color-selection --color red --show-palette


color-widget-palette

The color selection widget 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:


list-widget

The list 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!



Comments and Discussions
Linux Forum