When it comes to bash scripting, all the scripts are mainly focused on the command-line operation. Whether you need input from the user or display some messages, everything is done through the terminal. Most people writing scripts using Bash have no idea there are a set of GUI tools available. In this article, we are going to see about one such tool called Zenity - a simple program that enables you to create graphical (GTK+) dialog boxes in command-line and shell scripts.
Table of Contents
What is Zenity?
Zenity is a rewrite of gdialog, the GNOME port of dialog which allows you to create a set of widgets for different operations where users can interact with the script graphically. The widgets are based on the GTK toolkit.
Zenity is an open source program written using C programming language. It supports Linux, BSD and Windows.
Without further ado, let us see how to display graphical GTK+ dialog boxes from the commandline and shell scripts using Zenity.
How to install Zenity in Linux
First, check if zenity is installed and available to use by running the following commands:
$ which zenity /usr/bin/zenity
$ zenity --version 3.32.0
$ zenity --about
If zenity is not installed in your distribution, run the following commands depending on your distribution to install it.
Alpine Linux:
$ sudo apk add zenity
Arch Linux:
$ sudo pacman -S zenity
Fedora, RHEL, CentOS, Alma Linux and Rocky Linux:
$ sudo dnf install zenity
Debian, Ubuntu, Linux Mint, Pop OS:
$ sudo apt install zenity
openSUSE:
$ sudo zypper install zenity
1. Zenity Help & common options
For each widget, there is an associated help option through which you can get a set of supported options.
Run the following command to access the help section.
$ zenity --help
There are some common options that can be used along with any widget. These are not mandatory options but if used will leverage you to alter the widget behavior.
To get the list of common options run the following command.
$ zenity --help-general
We will see how these options work in the upcoming sections.
2. Message dialog box
A message dialog box will display an error, warning, info, and question dialog box. Depending upon the situation you have to use the appropriate dialog box in the script.
2.1. Error dialog box
To access the list of supported options for the error dialog box, run the following command:
$ zenity --help-error
To display the error dialog box in the script, use the following command. Here, the --error
flag will create the error dialog box and --text
flag will print the text message. You can see from the image there is an error icon associated with the dialog box.
zenity --error \ --title "Error Message" \ --width 500 \ --height 100 \ --text "Permission denied. Run with sudo or as root user."
You can also see from the above image, some of the common options like --width, --height are used to control the geometry of the dialog box. The flag --title is used to print the dialog bar with the title.
2.2. Warning dialog box
To access the list of supported options for the warning dialog box, run the following command:
$ zenity --help-warning
Use --warning
flag in the script to display the warning box and --text
flag to display the warning message.
zenity --warning \ --title "Warning Message" \ --width 500 \ --height 100 \ --text "Disk space exceeded the threshold limit. Check ASAP."
2.3. Info dialog box
To access the list of supported options for the info dialog box, run the following command:
$ zenity --help-info
Use --info
flag in the script to display the infobox and --text
flag to display the info message.
zenity --info \ --title "Info Message" \ --width 500 \ --height 100 \ --text "Installation completed successfully."
2.4. Question dialog box
To access the list of supported options for the question dialog box, run the following command:
$ zenity --help-question
The question dialog box will prompt a message along with a Yes or No option. If you press "Yes", the return code will be "zero" and for "No" the return code will be "one". You have to use the exit codes to write further logic in your scripts.
zenity --info \ --title "Info Message" \ --width 500 \ --height 100 \ --text "Installation completed successfully."
3. Text entry dialog box
To access the list of supported options for the text entry dialog box, run the following command:
$ zenity --help-entry
Text entry dialog box prompts input for the user. The flag --entry
to be used to create an entry dialog box. To display some text in the dialog box, use the --text
flag. The value entered in the text box will be printed in the terminal once you press ok. You have to store the output to a variable if you wish to further process the input from the text box like I did below.
$ USR=$(zenity --entry \ --width 500 \ --title "check user" \ --text "Enter the user name"); echo $USR
If you wish not to make the input text visible when typing, use the --hide-text
flag.
$ USR=$(zenity --entry \ --width 500 \ --title "check user" \ --text "Enter the user name" \ --hide-text); echo $USR
You can also set a default value inside the input box using the --entry-text
flag. You have to remove the value and provide your input or the existing value will be taken as default.
$ USR=$(zenity --entry \ --width 500 \ --title "check user" \ --text "Enter the user name" \ --entry-text $USER); echo $USR
4. Password dialog box
To access the list of supported options for the password dialog box, run the following command:
$ zenity --help-password
The password dialog box will accept username and password using the --username
and --password
flag. The output will be displayed as (Username | Password). You have to assign the output of the command to a variable and extract the username and password for further processing.
$ zenity --password --username
5. Text information dialog box
To access the list of supported options for the text information dialog box, run the following command:
$ zenity --help-text-info
The text information dialog box will print any text from a file or open a URL in the dialog box. For example, to read a file and display the text use the flag --filename
. In the below example, I am reading the /etc/hosts
file.
zenity --text-info \
--title "Hostname Information" \
--filename "/etc/hosts"
The --checkbox
flag can be used to get input from the user. A good example would be "Accepting license agreement". Unless you select the checkbox, ok button will be disabled.
zenity --text-info \
--title "Hostname Information" \
--filename "/etc/hosts" \
--checkbox "This is a checkbox"
6. Calendar dialog box
To access the list of supported options for the calendar dialog box, run the following command:
$ zenity --help-calendar
The calendar dialog box will display a calendar and allow you to choose a date. You have to store the output to a variable else the selected date will be printed in the terminal.
zenity --calendar \ --title="Select a Date" \ --text="Select Date to pull the employee record."
By default, today’s date is selected but we can also select a custom date by using --day
, --month
, and --year
flags.
zenity --calendar \ --title="Select a Date" \ --text="Select Date to pull the employee record." \ --year 2015 \ --month 7 \ --day 15
The default output format will be DD\MM\YY
. It is also possible to create a custom date output using the --date-format
flag.
zenity --calendar \ --title="Select a Date" \ --text="Select Date to pull the employee record." \ --date-format %m-%d-%y
7. Color selection dialog box
To access the list of supported options for the color selection dialog box, run the following command:
$ zenity --help-color-selection
The color selection dialog will display a palette and allow you to choose a color and the output will be RGB value. Use --color-selection
flag along with --show-palette
flag.
$ COLOR_RGB=$(zenity --color-selection --show-palette) $ echo $COLOR_RGB
8. File selection dialog box
To access the list of supported options for the file selection dialog box, run the following command:
$ zenity --help-file-selection
The file selection dialog will allow you to select files or directories and the path is displayed as the output. The flag --file-selection
should be used. There are a couple of flags that can be used in the file selection dialog.
--filename
=> Path to default file/directory--directory
=> Only directories to be selected--multiple
=> Allows to choose multiple file names--save
=> Set to save mode
zenity --file-selection \ --title "Select Files" \ --filename "/home/${USER}/" \ --multiple
In case of multiple selections, the file path will be separated using the "|"
symbol.
It is possible to set a custom separator using the --separator
flag. In the below example, I am using colon (:
) as the separator.
zenity --file-selection \ --title "Select Files" \ --filename "/home/${USER}/" \ --multiple \ --separator :
9. Forms dialog box
To access the list of supported options for the forms dialog box, run the following command:
$ zenity --help-forms
The forms dialog allows you to create forms. A good example is the new user signup form. Use --forms
flag to create form dialog box. There are a few additional flags that can be used along with the --forms
flag.
--add-entry
=> Add a new entry in the form dialog for the user to enter the input.--text
=> Text to be displayed in the dialog box.--add-password
=> Accepts password but will not display the value on screen.--calendar
=> Open calendar and choose a date from it.
Below is a simple example of a user sign-up form using forms dialog.
zenity --forms \ --text "Welcome to signup wizard" \ --add-entry "Enter the first name" \ --add-entry "Enter the last name" \ --add-entry "Enter login name" \ --add-password "Enter password"
The default separator for the input values is the "|"
symbol. You can also custom separator using --separator
flag.
10. Progress dialog box
To access the list of supported options for the progress bar dialog box, run the following command:
$ zenity --help-progress
Use --progress
flag to create a progress bar. In order to create a progress bar, you have to understand how it works. Two inputs should be provided from your side.
- The line that contains only the number with the
echo
command will be considered as the percentage of the progress. - The line that starts with the
#
symbol in theecho
command will be printed as the progress message.
( echo 10 echo "# Updating repository Index" sleep 5 echo 15 echo "# Reading input files" sleep 5 echo 70 echo "# Installing packages..." sleep 5 echo 100 echo "# Package Installation completed!" ) | zenity --title "Package Installation Progress Bar" --progress --auto-close
Once the progress bar is completed, you can make a dialog box to automatically close using --auto-close flag.
11. List dialog Box
To access the list of supported options for the list dialog box, run the following command:
$ zenity --help-list
The list dialog box allows you to create a list of rows and columns. Use --list
flag to create list dialog box and --column
flag to add columns.
$ zenity --list \ --column "Player" \ --column "Club" \ --column "Country" \ Messi PSG Argentina \ Neymar PSG Brazil \ Ronaldo Manu Portugal
Take a look at the above example. Using the --column
flag, I have created three columns. After columns are created, you can enter the value in the next lines which will be displayed for each row like as I did in the above image.
In the first column, checkbox or radio buttons can be created. To create a radio button, use --radiolist
flag and to create a checkbox, use --checklist
flag. When creating a radio list, it is mandatory to add TRUE or FALSE keywords as the first value for your row. True will select the radiolist or checkbox while false will leave the box unselected.
zenity --list \ --checklist \ --column "checkbox" \ --column "Player" \ --column "Club" \ --column "Country" \ FALSE Messi PSG Argentina \ FALSE Neymar PSG Brazil \ FALSE Ronaldo Manu Portugal
When you select the row and click ok, the value will be printed to the terminal with (|
) as the separator. By default, only the first column is printed to the terminal. To print the entire row, pass --print-column ALL
.
Conclusion
We have come to the end of the article. I have briefly explained what zenity is and the different widgets available to be used. You may not require GUI utilities all the time. However, when you need graphical GTK+ widgets in bash scripting, Zenity will come in handy amongst other GUI tools.
Resource:
Bash scripting guides:
- Bash Scripting – Case Statement
- Bash Scripting – Conditional Statements
- Bash Scripting – String Manipulation
- Bash Scripting – Printf Command Explained With Examples
- Bash Scripting – Indexed Array Explained With Examples
- Bash Scripting – Associative Array Explained With Examples
- Bash Scripting – For Loop Explained With Examples
- Bash Scripting – While And Until Loop Explained With Examples
- Bash Redirection Explained With Examples
- Bash Scripting – Variables Explained With Examples
- Bash Scripting – Functions Explained With Examples
- Bash Echo Command Explained With Examples In Linux
- Bash Heredoc Tutorial For Beginners
4 comments
You may want to take a look at yad instead of zenity for bash dialog boxes. Yad is the most flexible and polished tool for creating bash dialog boxes and, unlike zentity and whiptail, yad is being actively maintained.
We will look into it. Thanks for your suggestion.
For section “10. Progress dialog box”, I’d like to know how to get a return value that reflects error status ! let’s say that something went wrong when reading input files or setting parameters or copying files and an exit 1 command was properly executed making the progress bar to come to an end and to return control to the script. In that sense, I see that echo $? won’t work !
John,
You are right. The reason you will always get echo $? = 0 irrespective of whatever exit code the logic throws is because the last run command in the pipe is the zenity progress bar command which is going to return you zero unless you cancel(-1) it.
One way to capture the exit code is to use bash strict mode and set “set -o pipefail”.
set -o pipefail
( echo 50
echo “# Installing xxx package…”
apt install xxx -y
if [[ $? -ne 0 ]]; then
exit 2
fi
sleep 5
echo 100
echo “# Package Installation completed!”
) | zenity –title “Package Installation Progress Bar” –progress –auto-close
echo “Exit code from the progress operation is : $?”
Above is the same snippet I used in section 10 but with little modification. I am forcing exit code 2 if the package installation is failed and the remaining steps will be skipped.
Now If I try to capture the exit code outside of the progress bar operation it gives me 2 as expected.
karthick@HP-NOTEBOOK:~/Documents/zenity_test$ sudo bash -x zenity.sh
+ set -o pipefail
+ echo 50
+ echo ‘# Installing xxx package…’
+ apt install xxx -y
+ zenity –title ‘Package Installation Progress Bar’ –progress –auto-close
WARNING: apt does not have a stable CLI interface. Use with caution in scripts.
E: Unable to locate package xxx
+ [[ 100 -ne 0 ]]
+ exit 2
+ echo ‘Exit code from the progress operation is : 2’
Exit code from the progress operation is : 2