How to Add a GUI to Linux Shell Scripts

A zenity information window launched from an Ubuntu terminal.

You can use GUI windows, sliders, radio buttons, progress bars, and so on. in your Bash scripts. Learn how to use the zenity toolbox and breathe new life into your Bash scripts. We will show you how.

Bash Script is a powerful programming language and as it is integrated with the Bash shell, it is easily accessible to all. This is an easy language to start programming. As it is interpreted, you do not need to compile your scripts. As soon as you have edited the script file and made it executable, you can run it. This makes the coding, execution, and debugging cycle very efficient.

Bash scripts mainly raise two complaints among users. The first is speed. Because the Bash shell interprets script commands, they do not run as fast as the compiled code. However, it's like complaining that a tractor is not as fast as a car; they are destined for different things.

There are two types of speed, however. You can often associate a quick script and use it to perform a task much faster than developing a solution in a Web environment. compiled language, such as C.

The second complaint of users of Bash scripts is the user interface, it is a terminal window. Of course, sometimes the interface does not matter. If the only person who will use the script is its author, the interface is probably not so important. This does not matter either for scripts that perform background processing and a batch type. Typically, such scripts do not require much (if any) interaction from the user

There are cases where you need something a little more intuitive and modern than the terminal window. Most people know a graphical user interface (MISTLETOE). To provide users with the smoothest possible experience, you must create and use GUI elements from your scripts.

The zenity app

Zenity allows you to integrate a wide range of GUI elements into your Bash scripts. His a powerful toolbox this gives your scripts an impression of modernity and a contemporary and familiar appearance.

zenity is preinstalled on the Ubuntu, Fedora and Manjaro distributions. This is part of GNOME. If you use KDE, you might want to check kdialog instead, although zenity is running on any desktop environment.

The examples in this article show you how to create the different dialog windows from the command line, how to capture their return values ​​and user selections in variables, and how to use dialog windows in scripts.

We end with a small application that uses the three types of dialog windows.

The calendar dialog window

A calendar dialog box allows someone to select a date. To create one with zenity, you need only one command of two words:

zenity –calendar

The calendar dialog window appears. This has all the features you expect from a standard date picker. You can change the month and year and click on a day to select that date. By default, today's date is highlighted when the window appears.

A zenity calendar window from July 2019.

Click "OK" to close the dialog box and select the date highlighted. Double-clicking on a date does the same thing.

If you do not want to choose a date, click "Cancel", press the "Esc" key on your keyboard, or close the dialog box.

A zenity calendar window with August 19, 2019 selected.

In the example above, August 19, 2019 is selected. If the user clicks "OK", the calendar closes and the selected date is printed in the terminal window.

The date selected on the calendar (19/08/2019) displayed in the terminal window.

You can ignore the line, "GTKDialog mapped without transitional parent. This is discouraged. "

GTK means GIMP Tool Kit, which is the toolbox used to develop the GNOME interface. It was originally designed by the authors of the GNU Image Manipulation Program (GIMP). GNU means GNU's Not Unix.

The GTK engine warns zenity writers that they have used a non-standard GTK component.

Capturing the date value

Printing the date on the terminal does not do much for us. If we call this calendar from one of our scripts, we need to capture the selected date value in order to be able to do something useful with this script in our script. We will also slightly customize the calendar.

We will use the following options with the calendar. They must all be used with the double dash "-":

-text: Specifies a text string to display in the calendar. It replaces the default value, "Select a date below".
-Title: Sets the title of the calendar dialog window.
-day: Sets the selected day when the calendar opens.
-month: Sets the selected month when the calendar opens.
-year: Sets the selected year when the calendar opens.

We use a variable called ChosenDate to capture the date returned by the calendar. And we use echo $ ChosenDate to print this date in the terminal window.

Yes, we got the same result in the previous example, but here we have the selected date stored in a variable. In the previous example, it was printed and forgotten.

ChosenDate = $ (zenity – calendar – text "Choose a date" – title "How-To Geek Rota" – day 1 – month 9 – year 2019); echo $ ChosenDate

Now the calendar shows our prompt and the title of our window. The date is set to the start date we chose instead of the current date.

zenity calendar with a selected start date (September 1, 2019).

We can also customize the format of the date string returned during selection. The –date-format option must be followed by a format specifier. It is a chain of tokens defining the data and formats to be included in the output. The tokens are the same as those used with strftime () C language function and there is a large selection.

The tokens we use are:

%A: The full name of the day of the week.
%re: The day of the month as a number.
% m: The month in the form of a figure.
% y: The year in two digits (no century).
ChosenDate = $ (zenity – calendar –text "Pick a date" –title "How-To Geek Rota" –date-format = "% A% d /% m /% y" – day 1 – month 9 – year 2019); echo $ ChosenDate

Someone chooses a date:

Zenity calendar window with 16 September 2019 selected.

And the date is returned using our format. It displays the name of the day of the week, followed by the date in the European order: day, month, year.

Date in European format returned by a calendar in a terminal window.

The file selection dialog window: Choosing a file

The file selection dialog windows are quite complex. Users can browse the file system, highlight one or more files, and then click "OK" to select those files or cancel the selection.

zenity provides all these features, and more. And it's as easy to use as the Calendar dialog window.

The new options we will use are:

-Selection of file: Specifies to zenity that we want to use a file selection dialog.
-many: Allows someone to select more than one file.
-File-filter: Indicates to the file dialog window the types of files to display.
zenity –file-selection –tile "How-To-Geek" –multiple –file-filter = & # 39; *. mm * .png * .page * .sh * .txt & # 39;

The file selection dialog is as functional as any other file selection window.

the dialog window of the zenity file section with a selected folder.

The user can browse the file system and select the file of his choice.

Zenity file selection dialog with a selected file

We went through a new directory and selected a file called "button_hybrid.png".

When you click "OK", the file selection dialog closes. The file name and its path are printed in the terminal window.

The name of the file selected in a terminal window.

If you need to use the file name in any subsequent processing, you can capture it in a variable, just like for the calendar date.

The file selection dialog window: saving a file

If we add an option, we can turn the file selection dialog window into a file save dialog. The option is –save. We will also use the –confirm-overwrite option. This prompts the person to confirm that they want to overwrite an existing file.

Response = $ (zenity –file-selection –save –confirm-overwrite); echo $ Answer

The file save dialog window appears. Note that there is a text field in which someone can type a file name.

zenity file save the window.

The user can access the location of his choice in the file system, assign a name to the file or click on an existing file to overwrite it.

Saving zenity file with an existing file selected.

In the example above, the user has highlighted an existing file.

When he clicks "OK," a confirmation dialog box appears asking him to confirm that he wants to overwrite the existing file. Note that the file name appears in the warning dialog box. It's the kind of attention to detail that gives zenity its professional appearance.

If we had not used the –confirm-overwrite option, the file would have been silently overwritten.

The zenity write confirmation dialog

The file name is stored in the Response variable that displays in the terminal window.

A file name saved in a terminal window.

Notification dialog window

With zenity, the inclusion of clever dialogue windows in your scripts requires no effort. There are inventory dialogs that you can use to provide information, warnings, error messages, and questions to the user.

To create an error message dialog window, use the following command:

zenity –error –width 300 –text "Permission denied, can not write to file."

The new options we use are:

-Fault: Specifies to zenity that we want to use an error dialog window.
-width: Sets the initial width of the window.

The error dialog window appears at the specified width. It uses the standard GTK error icon.

Zenity error dialog window.

To create an information dialog window, use the following command:

zenity –info –width 300 –text "Update completed Click OK to continue."

The new option we use is –info, which tells zenity to create an information dialog window.

zenity information dialog window.

To create a question dialog window, use the following command:

zenity – question –width 300 –text "Are you happy to continue?"; echo $?

The new option we use is –question, which tells zenity to create a question dialog.

The $? is a special parameter. It contains the return value of the most recently executed leading pipeline. In general terms, it is the value of the last closed process. A value of zero means "OK" and a value of one or more means "Cancel".

This is a general technique that you can apply to any zenity dialog window. By checking this value in your script, you can determine whether data returned from a dialog window should be processed or ignored.

zenity question dialog.

We clicked "Yes", so the return code is a zero indicating "OK".

Zero (0) return code in a terminal window.

To create a warning dialog window, use the following command:

zenity –warning –title "Low space on hard disk" –width 300 –text "There may not be enough space on the hard disk to save the backup."

The new option we use is –warning, which tells zenity to create a warning dialog box.

The warning dialog window appears. This is not a question, so there is only one button.

Zenity warning dialog window.

Progress dialog window

You can use the zenity progress dialog box to display a progress bar indicating the degree of completion of the script.

The progress bar is advanced based on the values ​​that are piped from your script. To illustrate the principle, use the following command:

(for i in $ (seq 0 10 100); echo $ i; sleep 1; done)

The command breaks down like this:

The seq command goes through a sequence of 0 to 100, in steps of 10.
At each step, the value is stored in the variable i. This prints in the terminal window.
The command aborts for one second, because of the sleep 1 command.

We can use it with the zenity progress dialog window to show the progress bar. Note that we pass the output of the previous command in zenity:

(for i in $ (seq 0 10 100); echo $ i; sleep 1; fact) | zenity –progress –title "How-To Geek" – automatic closing

The new options we use are:

-progress: Tell zenity that we want to use a progress dialog window.
-Auto-close: Closes the dialog box when the progress bar reaches 100%.

The progress dialog box appears and the bar advances to 100%, paused for one second between each step.

zenity progress dialog.

We can use this concept of piping values ​​in zenity to include the progress dialog window in a script.

Enter this text in an editor and save it as "".

! / bin / bash

function worklist () {

echo "# first work item"
echo "25"
to sleep 1

echo "# Second work item"
echo "50"
to sleep 1

echo "# Third work item"
echo "75"
to sleep 1

echo "# last work item"
echo "100"
to sleep 1


working list | zenity –progress –title "How-To Geek" – self-close

exit 0

Here is the detail of the script:

The script defines a function called a worklist. It is there that you put your orders and instructions to perform a real job. Replace each of the sleep 1 commands with your actual commands.
zenity accepts echo lines "# …" and displays them in the progress dialog. Modify the text of these lines so that they transmit informative messages to the user.
Echo lines containing numbers, such as echo "25", are also accepted by zenity and set the value of the progress bar.
The worklist function is called and inserted in zenity.

Use this command to make the script executable:

chmod + x

Use this command to execute the script:


The script executes and the text message changes each time the script runs. The progress bar moves in steps to 100%.

Window of the zenity progress bar.

The dialogue window of scale

The scale dialog window allows someone to move a slider to choose a numerical value. This means that it can not enter a value that is too high or too low.

The new options we use are:

-ladder: Specifies to zenity that we want to use a dialog box of scale.
-Min-value: Sets the minimum value for the scale.
-Value max: Sets the maximum value of the scale.
-step: Sets the amount of cursor movement when the arrow keys are used. This does not affect the cursor movements if someone uses the mouse.
-value: Sets the initial value and the cursor position.

This is the command we use:

Response = $ (zenity –scale –title "How-To Geek" – text "Select magnification." –Min-value = 0 –max-value = 30 –step = 3 –value15); echo $ Answer

The cursor dialog window appears with the cursor set to 15.

zenity scale dialog window.

The user can move the cursor to select a new value.

zenity scale dialog with user selection

When it clicks "OK", the value is transferred to the response variable and printed in the terminal window.

zenity scale value in a terminal window.

The input dialog window

The input dialog window allows someone to enter text.

The new options we use are:

-Entrance: Specifies to zenity that we want to use an input dialog window.
-Entry-text: You can use it if you want to enter a suggested value in the text entry field. We use "" to force an empty field. This is not strictly necessary, but we wanted to document this option.

The complete command looks like this:

Response = $ (zenity –entry –text "Enter your search term" –title "Howe-To Geek" –entry-text = ""); echo $ Answer

A simple dialog box appears, containing a text entry field.

zenity input dialog window.

Someone can type and edit text.

Zenity input dialog window with text entered in the text field.

When he clicks "OK", the value he has entered is assigned to the Response variable. We use echo to print the value of the variable in the terminal window.

User text input term in a terminal window.

Put all together

Let's put these techniques together and create a functional script. The script will perform an analysis of the hardware information and present the results to the user in a scrolling text window. She can choose a long or short analysis type.

For this script, we will use three types of dialogue windows, two of which are new to us:

The first is a list dialog window. This allows someone to make a choice.
The second is a progress dialog that informs the user that something is happening and that he has to wait.
The third is a textual information window, which displays the results to the user.

Enter this text in an editor and save it as "".

#! / bin / bash

# View the hardware list for this computer

TempFile = $ (mktemp)

ListType = `zenity –width = 400 –height = 275 –list –radiolist
–title & # 39; Hardware Analysis & # 39;
–text & # 39; Select the type of analysis: & # 39;
–column & # 39; Select & # 39;
–column & # 39; Type of analysis & # 39; TRUE "Short" FALSE "Long" `

if [[ $? -eq 1 ]]; then

# they pressed Cancel or closed the dialog window
zenity –error –title = "Analysis refused" –width = 200
–text = "Ignored hardware scan"
exit 1

elif [ $ListType == “Short” ]; then

# they selected the short radio button
Flag = "- short"


# they selected the long radio button
Flag = ""

# search material information with the appropriate value in $ Flag
hwinfo $ flag | tee> (zenity –width = 200 –height = 100
–title = "Collating Information" –progress
–pulsate –text = "Hardware check …"
–auto-kill –auto-close)> $ {TempFile}

# Show hardware information in a drop-down window
zenity –width = 800 –height = 600
–title "Hardware Details"
–text-info –filename = "$ {TempFile}"

exit 0

Use this command to make it executable:

chmod + x

This script creates a temporary file whose name is contained in the TempFile variable:

TempFile = $ (mktemp)

The script uses the –list option to create a zenity dialog window called list dialog window. The "" characters at the end of the lines tell the script to treat them as a long, surrounded line. Here is the process:

We specify a width and height for the window.
The list dialog window supports columns. The –radiolist option makes the first column a column of radio buttons.
We define a title and a text prompt for the window.
We have defined the title of the first column on "Select". The contents of this column will consist of radio buttons.
We set the title of the second column to "Select" and we provide the contents of the second column. This column contains two labels: "Short" and "Long". The TRUE and FALSE indicators mean that the "Short" option is selected by default when the dialog window appears.
We store the result of this dialog in a variable called ListType.
ListType = `zenity –width = 400 –height = 275 –list –radiolist
–title & # 39; Hardware Analysis & # 39;
–text & # 39; Select the type of analysis: & # 39;
–column & # 39; Select & # 39;
–column & # 39; Type of analysis & # 39; TRUE "Short" FALSE "Long" `

If the user presses "Cancel", we do not need to check the value in ListType, we can just leave. If he presses "OK", we need to know if he has selected the "Short" or "Long" radio button:

The special parameter $? is zero if the user has pressed "OK". It is equal to a s & he pressed "Cancel" or closed the window.
If it's worth it, the script displays an error information dialog window and closes. If he presses "OK", we proceed to test the value in the ListType variable.
If the ListType variable contains the value "Short", the script sets a variable called Flag equal to "-short".
If the ListType variable does not contain the value "Short", it must contain the value "Long". The script sets a variable called Flag equal to "", which is an empty string.
The script uses the Flag variable in the next section.
if [[ $? -eq 1 ]]; then

# they pressed Cancel or closed the dialog window
zenity –error –title = "Analysis refused" –width = 200 –text = "Hardware scan ignored"
exit 1

elif [ $ListType == “Short” ]; then

# they selected the short radio button
Flag = "- short"


# they selected the long radio button
Flag = ""

Now that the script knows what type of analysis the user wants, we can perform hardware information analysis:

The script calls the hwinfo command and passes it to the Flag variable.
If Flag contains "-short", the hwinfo command performs a short scan. If the Flag value is "", nothing goes to hwinfo and a long default scan is done.
The script directs the output of hwinfo in tee. tee sends the output in zenity and the TempFile.
The script creates a progress bar dialog. It defines the width and height of the dialog window, as well as the title and the prompt texts.
The script can not know in advance how much information is generated by the hwinfo command. It can not therefore set the progress bar to advance 100% correctly. The –pulsate option causes the progress dialog box to display a moving indicator. This informs the user that something is happening and that he should wait.
The –auto-kill option ends the script if someone clicks on "Cancel".
The –auto-close option automatically closes the progress dialog box at the end of the monitored process.
# search material information with the appropriate value in $ Flag
hwinfo $ flag | tee> (zenity –width = 200 –height = 100
–title = "Collating Information" –progress
–pulsate –text = "Hardware check …"
–auto-kill –auto-close)> $ {TempFile}

Once the hwinfo analysis is complete, the script calls zenity to create a textual information dialog window with the -text-info option. The Text Information dialog window displays the contents of the TempFile file:

The script defines the width and height of the dialog window and the title text.
The –flename option is used to read the contents of the file contained in the TempFIle variable.
# Show hardware information in a drop-down window
zenity –width = 800 –height = 600
–title "Hardware Details"
–text-info –filename = "$ {TempFile}"

When the user closes the textual information dialog window, the script closes.

exit 0

Let's turn it on and take a look.


The list box appears. The "Short" option is selected by default.

Choose "Long" and click "OK".

The progress window appears with a sliding indicator. It remains on the screen until the hardware analysis is complete.

Progress window with sliding indicator.

When the hardware scan is complete, the textual information dialog box appears with the details of the scan.

Scanning information of the material into a textual information dialog window.

Click OK. "

Even an inflexible command-line jockey must admit that a few dialog windows with a graphical interface can give a Bash script a professional touch.


Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.