Zenity displays GTK dialogs from the command line, and the dialogs are the interface between the bash script and the user when the script needs input or needs to show progress. The tool works over X forwarding, which means the dialogs appear on the user's local display while the script runs on the remote server. This article covers the dialog types, the patterns for the headless environments, and the scenarios where a GUI dialog is the right interface for a bash script.
The dialog types and their use cases
Zenity provides info, warning, error, question, entry, password, progress and file-selection dialogs. The info dialog shows a message, the question dialog asks for confirmation, the entry dialog collects text input, and the progress dialog shows a bar that the script updates through its stdin. The password dialog collects a password without echoing it.
The X forwarding requirement
Zenity needs a display, and the headless server has none. The X forwarding through SSH, ssh -X, provides the display from the user's local machine, and the dialog appears on the user's screen while the script runs on the server. The requirement is that the user connects with X forwarding and that the server has the X authentication configured.
The progress dialog with the piped updates
The progress dialog reads updates from stdin, and the script writes percentages to the dialog's stdin as the operation progresses:
for i in $(seq 1 100); do echo $i; sleep 0.1; done | zenity --progress --title="Processing"
and the progress bar updates as the loop feeds numbers to the pipe.
The practical patterns and the limitations
Zenity is the right interface for the interactive scripts that the administrator runs manually, the scripts that need a confirmation before the destructive operation and that report progress during the long operation. The tool is not the right interface for the automated scripts, the cron jobs and the CI pipelines that run without a display, and the script that uses zenity should check that a display is available before showing the dialog.
The zenity tool is the GUI interface that the bash script uses for interactive dialogs, and the tool is the bridge between the terminal script and the graphical desktop.
Installation and X forwarding
Zenity installs from the distribution repository. The X forwarding setup requires the xauth package on the server, the X11Forwarding yes in the sshd_config and the SSH client with the -X flag. The dialog appears on the client display through the tunnel.
Dialog types and return values
Zenity dialog types map to interaction patterns: info for messages, warning for warnings, error for errors, entry for text input, password for hidden input, file-selection for paths. The exit code indicates the user action: 0 for OK, 1 for cancel.
The entry dialog collects text. The password dialog hides characters. The file selection returns a path.
Progress dialog
The progress dialog reads updates from stdin:
(echo 10; sleep 1; echo 50; sleep 1; echo 100) | zenity --progress --auto-close
Question dialog
zenity --question --text=Continue && rm -rf /tmp/*
The && operator runs rm only when the user confirms.
List dialog
The list dialog shows a table, and the user selects rows. The checklist variant adds checkboxes.
Notification
zenity --notification --text=Done --timeout=5
Limitations
Zenity works only with a display. The whiptail tool is the text-mode alternative.
Closing
Zenity is the tool that the bash script uses for graphical interaction, and the dialogs appear on the user display through X forwarding.
The zenity tool provides the graphical dialog interface that the bash script needs for the interactive operations: the confirmation before the destructive action, the text input for the configuration, the progress display for the long-running operation and the file selection for the data location. The dialogs appear on the user's display through the X forwarding or through the local display server, and the interaction is the input and the output that the script processes.
The zenity command vocabulary and the option reference
The zenity command has a general form: zenity --type [options]. The --type selects the dialog type, and the options customize the appearance and the behavior. The --title sets the window title, --text sets the dialog text, --width and --height set the dimensions, --timeout sets the auto-close timer and --icon-name sets the icon. The --ok-label and --cancel-label customize the button text, and the --extra-button adds additional buttons.
The return value of zenity is the dialog's result: the entry dialog returns the text, the list returns the selection, the calendar returns the date, and the file selection returns the path. The exit code indicates the user action: 0 for the OK button, 1 for the Cancel button, 5 for the timeout. The exit code is the signal that the script uses to distinguish the confirmed action from the cancelled one.
The scale and the color selection dialogs
The scale dialog provides a slider for the numeric input:
RESULT=$(zenity --scale --title="Volume" --min-value=0 --max-value=100 --value=50 --step=5)
and the slider returns the value that the user selected. The color selection dialog provides a color picker:
COLOR=$(zenity --color-selection --title="Pick a color")
and the color picker returns the color in the hex format. These dialogs are the input widgets that the GUI applications provide, made available to the bash scripts through zenity.
The forms dialog for the multi-field input
The forms dialog provides multiple input fields in one dialog, and the form is the pattern for the structured input that the entry dialog cannot provide alone:
RESULT=$(zenity --forms --title="Server setup" \
--add-entry="Hostname" \
--add-entry="IP address" \
--add-password="Password")
and the form returns the fields separated by pipes, the parsing that the script performs with the IFS variable. The forms dialog is the tool for the structured input that needs multiple fields, and the multiple fields are the form that the GUI application would provide as a dialog with multiple text boxes.
The text info dialog for displaying files
The text info dialog displays the content of a file or a long text in a scrollable window:
zenity --text-info --title="Release notes" --filename=/srv/RELEASE-NOTES.txt
and the text info dialog is the tool for displaying the long text that the dialog text parameter cannot hold. The --checkbox option adds a checkbox to the bottom of the dialog, the checkbox that the license agreement uses, and the checkbox return value indicates whether the user checked it.
The error handling patterns with zenity
The zenity dialogs return exit codes that the script checks, and the error handling pattern wraps the zenity call in an if statement:
if zenity --question --text="Deploy to production?"; then
echo "deploying"
else
echo "cancelled"
exit 0
fi
and the if statement branches on the dialog result, the deployment proceeding only when the user confirms. The pattern is the one that the destructive operations need, and the pattern is the safety gate that the interactive scripts provide.
The zenity in the deployment scripts
The deployment script that uses zenity is the script that the operator runs interactively, and the script combines the zenity dialogs with the production operations. The script that deploys the application:
VERSION=$(zenity --entry --title="Deploy" --text="Version to deploy:")
if [ -z "$VERSION" ]; then exit 0; fi
if zenity --question --text="Deploy version $VERSION?"; then
(echo 25; echo "Building"; sleep 2
echo 50; echo "Testing"; sleep 2
echo 75; echo "Deploying"; sleep 2
echo 100) | zenity --progress --auto-close
zenity --info --text="Deployed $VERSION"
fi
and the script combines the entry dialog for the version input, the question dialog for the confirmation, the progress dialog for the deployment progress and the info dialog for the completion. The script is the complete deployment tool that the operator runs from the terminal, and the dialogs are the interface that makes the tool interactive.
The security considerations for the GUI dialogs
The GUI dialog that collects the password displays the password in the dialog, and the dialog is the display that the other users on the same X display can see. The security practice for the password dialogs is the password dialog with the --hide-text option, which is the default for the --password dialog type. The password that the dialog collects is the password that the script uses, and the password should be stored in a variable rather than in a file.
The X forwarding that the dialog uses is the encrypted tunnel, and the tunnel prevents the network eavesdropping from seeing the dialog content. The security of the X forwarding is the security of the SSH tunnel, and the security is the same as the SSH transport that the bastion article described.
The zenity and the notify-send comparison
Zenity provides the dialogs, and notify-send provides the desktop notifications. The two tools serve different interaction patterns: the dialog requires the user's immediate attention, the notification does not. The script that uses zenity for the confirmation and notify-send for the notification is the script that matches the interaction pattern to the urgency.
The zenity notification icon overlaps with the notify-send functionality, and the choice between them is a preference: zenity uses GTK, notify-send uses the desktop notification specification, and the appearance depends on the desktop environment. The script that uses both is the script that matches the notification to the desktop environment, and the script that uses one consistently is the script that the user recognizes.
The complete checklist for the zenity deployment
The checklist for the zenity usage in the interactive scripts is the working order. Install zenity on the server or ensure the X forwarding for the remote execution. Choose the dialog types that match the interaction patterns. Use the entry and password dialogs for the input collection. Use the progress dialog for the long-running operations. Use the question dialog for the destructive operation confirmations. Use the list dialog for the structured selections. Check the exit codes for the dialog results. Test the X forwarding before the production use. And document the dialogs in the script's help, because the interactive script that the operator does not understand is the script that the operator does not use.
The zenity dialogs that the deployment script uses are the same dialogs that the system configuration tools use: the confirmation before the destructive action, the input for the configuration values, the progress display for the long-running operation. The dialogs are the GTK widgets that the desktop environment renders, and the rendering is the visual interface that the user interacts with.
The script that uses zenity for the interactive deployment is the script that the operator runs from the terminal on the management workstation, and the X forwarding makes the dialogs appear on the operator's display while the operations happen on the production server. The separation between the display and the operation is the security property that the bastion article described, and the separation is the property that the zenity dialogs preserve.
The zenity tool that the production script uses for the interactive deployment is the tool that the operator's workstation already has installed, because the tool is the GTK dialog library that every desktop environment includes. The installation that the script needs is not on the server but on the workstation, and the distinction between the server-side script and the client-side display is the architecture that the X forwarding provides.
The dialogs that zenity shows are the widgets that the operator expects from the desktop applications: the buttons, the text fields, the checkboxes, the progress bars, and the dialogs are the familiar interface that the operator recognizes without reading the script. The familiarity is the usability feature, and the usability is the reason that the GUI dialogs are the interface for the scripts that the operator runs interactively.
The zenity tool's role in the production script toolkit is the interface for the human-in-the-loop operations: the deployments that need a confirmation, the cleanups that need a warning, the maintenance that needs a progress display. The scripts that run without human interaction use the command-line arguments and the configuration files, and the scripts that run with the human interaction use the zenity dialogs. The choice between the two is the choice between the automated and the manual, and the choice is the script's design decision.
The zenity tool's future in the bash script ecosystem is stable: the tool is maintained, the GTK libraries are maintained, and the dialogs work on every desktop environment. The alternative tools, the yad tool that is the zenity fork with more features and the whiptail tool that is the text-mode alternative, are the options that the script can choose from, and the options are the choices that the script's environment determines. The zenity that works on every desktop is the default choice, and the default is the one that the production script should use unless there is a reason to choose otherwise.