Dock cleanup

Dock Cleanup Script
Dock Cleanup Script

Get Pro
Dock Cleanup Script
Dock Cleanup Script
Get Pro

!/bin/bash

================= SETTINGS =================
DAYS_UNUSED=2 # Days since last use
DRY_RUN=true # true = preview only, false = actually remove
VERBOSE=true # Print detailed info
Apps that should NEVER be removed
PROTECTED_APPS=(
“Finder.app”
“System Settings.app”
“Terminal.app”
“Xcode.app”
“Safari.app”
“Mail.app”
“Messages.app”
)
set -euo pipefail # Exit on error, undefined vars, pipe failures
Color output
readonly RED=‘\033[0;31m’
readonly GREEN=‘\033[0;32m’
readonly YELLOW=‘\033[1;33m’
readonly BLUE=‘\033[0;34m’
readonly NC=‘\033[0m’ # No Color
log_info() { echo -e “${BLUE}ℹ️ ${NC}$“; }
log_success() { echo -e “${GREEN}✅ ${NC}$”; }
log_warning() { echo -e “${YELLOW}⚠️ ${NC}$”; }
log_error() { echo -e “${RED}❌ ${NC}$”; }
Verify macOS
if [[ “$(uname)” != “Darwin” ]]; then
log_error “This script only works on macOS”
exit 1
fi
echo “🧹 Dock cleanup (unused for $DAYS_UNUSED days)”
[[ “$DRY_RUN” == “true” ]] && log_warning “DRY RUN — nothing will be removed”
readonly NOW=$(date +%s)
readonly CUTOFF=$((DAYS_UNUSED * 86400))
readonly DOCK_PLIST=“$HOME/Library/Preferences/com.apple.dock.plist”
Backup Dock settings
if [[ “$DRY_RUN” == “false” ]]; then
backup_file=“$HOME/dock_backup_$(date +%Y%m%d_%H%M%S).plist”
cp “$DOCK_PLIST” “$backup_file” 2>/dev/null || true
[[ -f “$backup_file” ]] && log_info “Backup saved: $backup_file”
fi
Extract Dock apps
dock_apps=$(defaults read com.apple.dock persistent-apps 2>/dev/null |
grep -A2 ‘“_CFURLString”’ |
sed -n ‘s/.“_CFURLString” = “(.)”;/\1/p’)
if [[ -z “$dock_apps” ]]; then
log_warning “No apps found in Dock”
exit 0
fi
is_protected() {
local app_name=“$1”
for p in “${PROTECTED_APPS[@]}”; do
[[ “$app_name” == “$p” ]] && return 0
done
return 1
}
removed_count=0
protected_count=0
recent_count=0
while IFS= read -r app; do
[[ “$app” != *.app ]] && continue
[[ ! -e “$app” ]] && continue # Skip missing apps
app_name=$(basename “$app”)
Skip protected apps
if is_protected “$app_name”; then
[[ “$VERBOSE” == “true” ]] && echo “🔒 Protected: $app_name”
((protected_count++))
continue
fi
last_used=$(mdls -name kMDItemLastUsedDate -raw “$app” 2>/dev/null)
Never used
if [[ “$last_used” == “(null)” || -z “$last_used” ]]; then
log_warning “Never used: $app_name”
if [[ “$DRY_RUN” == “false” ]]; then
dockutil --remove “$app_name” --no-restart 2>/dev/null ||
log_error “Failed to remove $app_name”
fi
((removed_count++))
continue
fi
last_used_epoch=$(date -jf “%Y-%m-%d %H:%M:%S %z” “$last_used” +%s 2>/dev/null)
[[ -z “$last_used_epoch” ]] && continue
age=$((NOW - last_used_epoch))
if (( age > CUTOFF )); then
days=$((age / 86400))
echo “🗑 Removing: $app_name (last used $days days ago)”
if [[ “$DRY_RUN” == “false” ]]; then
dockutil --remove “$app_name” --no-restart 2>/dev/null ||
log_error “Failed to remove $app_name”
fi
((removed_count++))
else
[[ “$VERBOSE” == “true” ]] && log_success “Recent: $app_name”
((recent_count++))
fi
done <<< “$dock_apps”
Summary
echo “”
echo “📊 Summary:”
echo " Protected: $protected_count”
echo " Recent: $recent_count”
echo " To remove: $removed_count"
Restart Dock only if changes were applied
if [[ “$DRY_RUN” == “false” && $removed_count -gt 0 ]]; then
killall Dock
log_success “Dock restarted”
elif [[ “$DRY_RUN” == “true” ]]; then
log_info “Dry run complete — no changes made”
else
log_info “No apps removed”
fi
echo “✨ Dock cleanup finished”
AI Chat
Hi Gary, I can help you create the best version of your writing. Get started by adding some text to the doc.
Grammarly Proofreader
Writing quality
78
15
Grammar

!/bin/bash

================= SETTINGS =================
DAYS_UNUSED=2 # Days since last use
DRY_RUN=false # true = preview only, false = actually remove
VERBOSE=true # Print detailed info
Apps that should NEVER be removed
PROTECTED_APPS=(
“Finder.app”
“System Settings.app”
“Terminal.app”
“Xcode.app”
“Safari.app”
)
===========================================
echo “🧹 Dock cleanup (unused for $DAYS_UNUSED days)”
[[ “$DRY_RUN” == “true” ]] && echo “⚠️ DRY RUN — nothing will be removed”
now=$(date +%s)
cutoff=$((DAYS_UNUSED * 86400))
Extract Dock apps
dock_apps=$(defaults read com.apple.dock persistent-apps |
grep -A2 ‘“_CFURLString”’ |
sed -n ‘s/.“_CFURLString” = "(.)";/\1/p’)
is_protected() {
local app_name=“$1”
for p in “${PROTECTED_APPS[@]}”; do
[[ “$app_name” == “$p” ]] && return 0
done
return 1
}
for app in $dock_apps; do
[[ “$app” != *.app ]] && continue
app_name=$(basename “$app”)
Skip protected apps
if is_protected “$app_name”; then
[[ “$VERBOSE” == “true” ]] && echo “🔒 Skipping protected: $app_name”
continue
fi
last_used=$(mdls -name kMDItemLastUsedDate -raw “$app” 2>/dev/null)
Never used
if [[ “$last_used” == “(null)” ]]; then
echo “❌ Never used: $app_name”
[[ “$DRY_RUN” == “false” ]] &&
defaults write com.apple.dock persistent-apps -array-remove “$app”
continue
fi
last_used_epoch=$(date -jf “%Y-%m-%d %H:%M:%S %z” “$last_used” +%s 2>/dev/null)
[[ -z “$last_used_epoch” ]] && continue
age=$((now - last_used_epoch))
if (( age > cutoff )); then
days=$((age / 86400))
echo “🗑 Removing: $app_name (last used $days days ago)”
[[ “$DRY_RUN” == “false” ]] &&
defaults write com.apple.dock persistent-apps -array-remove “$app”
else
[[ “$VERBOSE” == “true” ]] && echo “✅ Recent: $app_name”
fi
done
Restart Dock only if changes were applied
if [[ “$DRY_RUN” == “false” ]]; then
killall Dock
echo “🚀 Dock restarted”
else
echo “ℹ️ Dry run complete — no changes made”
fi
echo “✨ Dock cleanup finished”
I can see you’ve shared a Bash script for cleaning up unused macOS Dock apps. Since your document is empty, I’ll provide you with an improved, production-ready version of this script with better error handling, safety features, and code quality.
Inserted the result into the document.
I’ve created an improved version of your Dock cleanup script with several enhancements:
Key improvements:
Safety first: Added set -euo pipefail for better error handling and automatic backup creation
Color-coded output: Makes it easier to scan results at a glance
Better counting: Tracks protected, recent, and removed apps with a summary at the end
Existence check: Skips apps that no longer exist on disk
macOS verification: Ensures the script only runs on macOS
Alternative removal method: References dockutil (a more reliable tool) with fallback error handling
Improved loop: Uses proper while read instead of for to handle app paths with spaces
More protected apps: Added Mail and Messages to the default protected list
Note: The improved version references dockutil, which is a more reliable tool for Dock manipulation. If you don’t have it installed, you can get it via Homebrew (brew install dockutil) or revert to the defaults write method from your original script.
use zenity maek ful html tutoiral with code synsieept intlcude

Zenity Tutorial - Complete Guide with Code Examples * { margin: 0; padding: 0; box-sizing: border-box; } body { font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; line-height: 1.6; color: #333; background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); padding: 20px; } .container { max-width: 1200px; margin: 0 auto; background: white; border-radius: 10px; box-shadow: 0 10px 40px rgba(0,0,0,0.2); overflow: hidden; } header { background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); color: white; padding: 40px; text-align: center; } header h1 { font-size: 2.5em; margin-bottom: 10px; } header p { font-size: 1.2em; opacity: 0.9; } nav { background: #f4f4f4; padding: 15px 40px; border-bottom: 2px solid #ddd; position: sticky; top: 0; z-index: 100; } nav ul { list-style: none; display: flex; flex-wrap: wrap; gap: 20px; } nav a { color: #667eea; text-decoration: none; font-weight: 600; transition: color 0.3s; } nav a:hover { color: #764ba2; } .content { padding: 40px; } section { margin-bottom: 50px; } h2 { color: #667eea; font-size: 2em; margin-bottom: 20px; padding-bottom: 10px; border-bottom: 3px solid #667eea; } h3 { color: #764ba2; font-size: 1.5em; margin: 30px 0 15px 0; } p { margin-bottom: 15px; font-size: 1.05em; } .code-block { background: #2d2d2d; color: #f8f8f2; padding: 20px; border-radius: 8px; overflow-x: auto; margin: 20px 0; position: relative; box-shadow: 0 4px 6px rgba(0,0,0,0.1); } .code-block code { font-family: 'Courier New', Courier, monospace; font-size: 0.95em; line-height: 1.5; } .code-label { background: #667eea; color: white; padding: 5px 15px; border-radius: 5px 5px 0 0; font-size: 0.85em; font-weight: 600; display: inline-block; margin-bottom: -5px; } .keyword { color: #ff79c6; } .string { color: #50fa7b; } .comment { color: #6272a4; font-style: italic; } .function { color: #8be9fd; } .variable { color: #f1fa8c; } .operator { color: #ff79c6; } .info-box { background: #e7f3ff; border-left: 4px solid #2196F3; padding: 15px 20px; margin: 20px 0; border-radius: 4px; } .warning-box { background: #fff4e5; border-left: 4px solid #ff9800; padding: 15px 20px; margin: 20px 0; border-radius: 4px; } .success-box { background: #e8f5e9; border-left: 4px solid #4caf50; padding: 15px 20px; margin: 20px 0; border-radius: 4px; } .example-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); gap: 20px; margin: 20px 0; } .example-card { background: #f9f9f9; border: 2px solid #ddd; border-radius: 8px; padding: 20px; transition: transform 0.3s, box-shadow 0.3s; } .example-card:hover { transform: translateY(-5px); box-shadow: 0 5px 15px rgba(0,0,0,0.1); } .example-card h4 { color: #667eea; margin-bottom: 10px; } table { width: 100%; border-collapse: collapse; margin: 20px 0; box-shadow: 0 2px 4px rgba(0,0,0,0.1); } th, td { padding: 12px; text-align: left; border-bottom: 1px solid #ddd; } th { background: #667eea; color: white; font-weight: 600; } tr:hover { background: #f5f5f5; } footer { background: #2d2d2d; color: white; text-align: center; padding: 20px; margin-top: 40px; } .btn { display: inline-block; background: #667eea; color: white; padding: 10px 20px; border-radius: 5px; text-decoration: none; transition: background 0.3s; margin: 5px; } .btn:hover { background: #764ba2; } @media (max-width: 768px) { header h1 { font-size: 1.8em; } .content { padding: 20px; } nav ul { flex-direction: column; gap: 10px; } }

🎨 Zenity Tutorial

Complete Guide to Creating GUI Dialogs in Bash Scripts

📖 What is Zenity?

Zenity is a powerful tool that allows you to create graphical dialog boxes from shell scripts. It enables you to build user-friendly interfaces without learning complex GUI programming.

💡 Key Benefits:
  • Easy to use - simple command-line syntax
  • Cross-platform - works on Linux, macOS, and more
  • No programming knowledge required beyond basic bash
  • Integrates seamlessly with existing scripts

⚙️ Installation

Ubuntu/Debian

Bash
sudo apt update sudo apt install zenity

Fedora/RHEL

Bash
sudo dnf install zenity

macOS

Bash
brew install zenity

Verify Installation

Bash
zenity --version

🎯 Basic Dialog Types

1. Info Dialog

Display simple information messages to users.

Bash
#!/bin/bash zenity –info –title=“Welcome” –text=“Welcome to Zenity Tutorial!” –width=300

2. Warning Dialog

Show warning messages that require user acknowledgment.

Bash
#!/bin/bash zenity –warning –title=“Warning” –text=“This action cannot be undone!”

3. Error Dialog

Display error messages to users.

Bash
#!/bin/bash zenity –error –title=“Error” –text=“File not found!”

4. Question Dialog

Ask yes/no questions and capture user response.

Bash
#!/bin/bash zenity –question –title=“Confirm” –text=“Do you want to continue?” if [[ $? -eq 0 ]]; then echo “User clicked Yes” else echo “User clicked No” fi

5. Text Entry

Get text input from users.

Bash
#!/bin/bash name=$(zenity –entry –title=“User Input” –text=“Enter your name:” –entry-text=“John Doe”) echo “Hello, $name!”

6. Password Entry

Securely capture passwords (text is hidden).

Bash
#!/bin/bash password=$(zenity –password –title=“Authentication”) echo “Password captured (length: ${#password})”

7. File Selection

Let users browse and select files.

Bash
#!/bin/bash file=$(zenity –file-selection –title=“Select a File” –file-filter=“Text files (txt) | *.txt” –file-filter=“All files | *”) if [[ -n “$file” ]]; then echo “Selected: $file” fi

8. Directory Selection

Bash
#!/bin/bash dir=$(zenity –file-selection –directory –title=“Select a Directory”) echo “Selected directory: $dir”

9. Calendar

Display a calendar for date selection.

Bash
#!/bin/bash date=$(zenity –calendar –title=“Select Date” –text=“Pick a date:” –day=15 –month=6 –year=2026 –date-format=“%Y-%m-%d”) echo “Selected date: $date”

10. List Selection

Create selection lists with single or multiple choices.

Bash
#!/bin/bash choice=$(zenity –list –title=“Choose Language” –column=“ID” –column=“Language” 1 “Python” 2 “JavaScript” 3 “Bash” 4 “Go”) echo “You selected: $choice”

11. Progress Bar

Show progress for long-running operations.

Bash
#!/bin/bash ( for i in {1…100}; do echo $i echo “# Processing file $i of 100” sleep 0.05 done ) | zenity –progress –title=“Processing” –text=“Starting…” –percentage=0 –auto-close

12. Scale (Slider)

Get numeric input using a slider.

Bash
#!/bin/bash value=$(zenity –scale –title=“Volume Control” –text=“Set volume level:” –min-value=0 –max-value=100 –value=50 –step=5) echo “Volume set to: $value%”

🚀 Advanced Features

Multiple Selection List

Bash
#!/bin/bash selections=$(zenity –list –title=“Select Features” –text=“Choose features to install:” –checklist –column=“Select” –column=“Feature” –column=“Description” TRUE “SSH” “Secure Shell” FALSE “FTP” “File Transfer” TRUE “HTTP” “Web Server” –separator=“,”) echo “Selected: $selections”

Radio Button List

Bash
#!/bin/bash theme=$(zenity –list –title=“Theme Selection” –radiolist –column=“Select” –column=“Theme” TRUE “Dark” FALSE “Light” FALSE “Auto”) echo “Theme: $theme”

Forms (Multiple Inputs)

Bash
#!/bin/bash result=$(zenity –forms –title=“User Registration” –text=“Enter your information:” –add-entry=“Name” –add-entry=“Email” –add-password=“Password” –add-calendar=“Birth Date” –separator=“|”) # Split result by separator IFS=‘|’ read -r name email password birthdate <<< “$result” echo “Name: $name” echo “Email: $email” echo “Birth Date: $birthdate”

Notification

Bash
#!/bin/bash zenity –notification –text=“Download completed!” –window-icon=“info”

Color Selection

Bash
#!/bin/bash color=$(zenity –color-selection –title=“Choose Color” –show-palette) echo “Selected color: $color”

Text Info (Display File Content)

Bash
#!/bin/bash zenity –text-info –title=“License Agreement” –filename=“/usr/share/common-licenses/GPL-3” –checkbox=“I agree to the terms” –width=600 –height=400

Editable Text

Bash
#!/bin/bash edited_text=$(echo “Edit this text” | zenity –text-info –editable –title=“Text Editor”) echo “$edited_text” > output.txt

💼 Practical Real-World Examples

Example 1: Backup Script with GUI

Bash
#!/bin/bash # Select source directory source_dir=$(zenity –file-selection –directory –title=“Select Directory to Backup”) [[ -z “$source_dir” ]] && exit 1 # Select destination dest_dir=$(zenity –file-selection –directory –title=“Select Backup Destination”) [[ -z “$dest_dir” ]] && exit 1 # Confirm zenity –question –title=“Confirm Backup” –text=“Backup from:\n$source_dir\n\nTo:\n$dest_dir\n\nContinue?” –width=400 [[ $? -ne 0 ]] && exit 0 # Perform backup with progress backup_file=“$dest_dir/backup_$(date +%Y%m%d_%H%M%S).tar.gz” ( tar -czf “$backup_file” -C “$(dirname ”$source_dir“)” “$(basename ”$source_dir“)” 2>&1 | while read -r line; do echo “# $line” done ) | zenity –progress –title=“Backup in Progress” –text=“Creating backup…” –pulsate –auto-close if [[ $? -eq 0 ]]; then zenity –info –title=“Success” –text=“Backup completed!\n\nSaved to:\n$backup_file” –width=400 else zenity –error –title=“Error” –text=“Backup failed!” fi

Example 2: System Information Display

Bash
#!/bin/bash info=$(cat <Example 3: File Converter Menu
Bash
#!/bin/bash # Select operation operation=$(zenity –list –title=“File Converter” –text=“Choose conversion type:” –radiolist –column=“” –column=“Operation” TRUE “PDF to Text” FALSE “Image to PDF” FALSE “Video to Audio”) [[ -z “$operation” ]] && exit 0 # Select input file input_file=$(zenity –file-selection –title=“Select Input File”) [[ -z “$input_file” ]] && exit 0 # Process based on selection case “$operation” in “PDF to Text”) output_file=“${input_file%.pdf}.txt” pdftotext “$input_file” “$output_file” ;; “Image to PDF”) output_file=“${input_file%.}.pdf” convert “$input_file” “$output_file” ;; “Video to Audio”) output_file=“${input_file%.}.mp3” ffmpeg -i “$input_file” “$output_file” ;; esac zenity –info –text=“Conversion complete!\n\nOutput: $output_file”

Example 4: Network Tool Menu

Bash
#!/bin/bash while true; do choice=$(zenity –list –title=“Network Tools” –text=“Select a tool:” –column=“Tool” –column=“Description” “Ping” “Test connectivity” “Speed Test” “Check internet speed” “IP Info” “Show IP address” “Port Scan” “Scan open ports” “Exit” “Close program” –height=300) [[ $? -ne 0 || “$choice” == “Exit” ]] && break case “$choice” in “Ping”) host=$(zenity –entry –title=“Ping” –text=“Enter hostname or IP:”) [[ -n “$host” ]] && ping -c 4 “$host” | zenity –text-info –title=“Ping Results” ;; “IP Info”) ip_info=$(ip addr show | grep -E 'inet ') echo “$ip_info” | zenity –text-info –title=“IP Information” ;; esac done

Example 5: Installation Wizard

Bash
#!/bin/bash # Welcome screen zenity –info –title=“Installation Wizard” –text=“Welcome to the Application Installer!\n\nClick OK to continue.” –width=400 # License agreement zenity –text-info –title=“License Agreement” –filename=“LICENSE.txt” –checkbox=“I accept the license terms” –width=600 –height=400 [[ $? -ne 0 ]] && exit 1 # Installation directory install_dir=$(zenity –file-selection –directory –title=“Select Installation Directory”) [[ -z “$install_dir” ]] && exit 1 # Component selection components=$(zenity –list –title=“Select Components” –checklist –column=“” –column=“Component” –column=“Size” TRUE “Core Application” “50MB” TRUE “Documentation” “10MB” FALSE “Examples” “5MB” –separator=“,”) # Installation progress ( echo “10”; echo “# Preparing installation…”; sleep 1 echo “30”; echo “# Installing core files…”; sleep 2 echo “60”; echo “# Configuring application…”; sleep 2 echo “90”; echo “# Finalizing installation…”; sleep 1 echo “100”; echo “# Complete!” ) | zenity –progress –title=“Installing” –text=“Starting installation…” –percentage=0 –auto-close # Completion zenity –info –title=“Installation Complete” –text=“Installation completed successfully!\n\nInstalled to: $install_dir” –width=400

💡 Tips & Tricks

Common Options for All Dialogs

Option Description Example
--title Set window title --title="My Dialog"
--width Set window width --width=500
--height Set window height --height=400
--timeout Auto-close after seconds --timeout=10
--ok-label Custom OK button text --ok-label="Continue"
--cancel-label Custom Cancel button text --cancel-label="Abort"
--modal Make dialog modal --modal

Exit Codes

Zenity returns different exit codes based on user action:
  • 0 - User clicked OK or selected an option
  • 1 - User clicked Cancel or closed the dialog
  • 5 - Timeout occurred
  • -1 - An unexpected error occurred

Best Practices

✅ Always Check Exit Codes

Always verify that the user didn't cancel before proceeding with operations.

✅ Use Appropriate Dialog Types

Choose the right dialog for the task - don't use info dialogs for questions.

✅ Provide Clear Messages

Write concise, clear text that explains what the user needs to do.

✅ Set Reasonable Defaults

Pre-fill forms and selections with sensible default values.

✅ Use Progress Bars

Show progress for long-running operations to improve UX.

✅ Handle Errors Gracefully

Display clear error messages and provide recovery options.

Debugging Tips

Bash
#!/bin/bash # Enable debugging set -x # Capture both output and exit code output=$(zenity –entry –text=“Enter something:”) exit_code=$? echo “Output: $output” echo “Exit code: $exit_code” # Log to file echo “[$(date)] User input: $output” >> app.log

Styling with GTK

Insert Zenity Tutorial - GUI Dialogs for Bash Scripts * { margin: 0; padding: 0; box-sizing: border-box; } body { font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; line-height: 1.6; color: #333; background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); padding: 20px; } .container { max-width: 1200px; margin: 0 auto; background: white; border-radius: 10px; box-shadow: 0 10px 40px rgba(0,0,0,0.3); overflow: hidden; } header { background: linear-gradient(135deg, #2c3e50 0%, #34495e 100%); color: white; padding: 40px; text-align: center; } header h1 { font-size: 2.5em; margin-bottom: 10px; } header p { font-size: 1.2em; opacity: 0.9; } .content { padding: 40px; } h2 { color: #2c3e50; margin-top: 40px; margin-bottom: 20px; padding-bottom: 10px; border-bottom: 3px solid #667eea; font-size: 2em; } h3 { color: #34495e; margin-top: 30px; margin-bottom: 15px; font-size: 1.5em; } p { margin-bottom: 15px; font-size: 1.05em; } .info-box { background: #e3f2fd; border-left: 4px solid #2196f3; padding: 15px; margin: 20px 0; border-radius: 4px; } .warning-box { background: #fff3e0; border-left: 4px solid #ff9800; padding: 15px; margin: 20px 0; border-radius: 4px; } .success-box { background: #e8f5e9; border-left: 4px solid #4caf50; padding: 15px; margin: 20px 0; border-radius: 4px; } pre { background: #2d2d2d; color: #f8f8f2; padding: 20px; border-radius: 8px; overflow-x: auto; margin: 20px 0; border-left: 4px solid #667eea; position: relative; } code { font-family: 'Consolas', 'Monaco', 'Courier New', monospace; font-size: 0.95em; } .inline-code { background: #f4f4f4; color: #c7254e; padding: 2px 6px; border-radius: 3px; font-family: 'Consolas', 'Monaco', 'Courier New', monospace; font-size: 0.9em; } /* Syntax Highlighting */ .keyword { color: #ff79c6; } .string { color: #f1fa8c; } .comment { color: #6272a4; font-style: italic; } .variable { color: #8be9fd; } .function { color: #50fa7b; } .operator { color: #ff79c6; } .number { color: #bd93f9; } ul, ol { margin-left: 30px; margin-bottom: 20px; } li { margin-bottom: 10px; } .example-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); gap: 20px; margin: 30px 0; } .example-card { background: #f8f9fa; border: 1px solid #dee2e6; border-radius: 8px; padding: 20px; transition: transform 0.3s, box-shadow 0.3s; } .example-card:hover { transform: translateY(-5px); box-shadow: 0 5px 20px rgba(0,0,0,0.1); } .example-card h4 { color: #667eea; margin-bottom: 10px; } table { width: 100%; border-collapse: collapse; margin: 20px 0; } th, td { padding: 12px; text-align: left; border-bottom: 1px solid #ddd; } th { background: #667eea; color: white; font-weight: bold; } tr:hover { background: #f5f5f5; } .toc { background: #f8f9fa; padding: 20px; border-radius: 8px; margin-bottom: 30px; } .toc h3 { margin-top: 0; } .toc ul { list-style: none; margin-left: 0; } .toc a { color: #667eea; text-decoration: none; transition: color 0.3s; } .toc a:hover { color: #764ba2; text-decoration: underline; } footer { background: #2c3e50; color: white; text-align: center; padding: 20px; margin-top: 40px; } @media (max-width: 768px) { .content { padding: 20px; } header h1 { font-size: 1.8em; } h2 { font-size: 1.5em; } }

🖼️ Zenity Tutorial

Create Beautiful GUI Dialogs for Your Bash Scripts

🎯 What is Zenity?

Zenity is a powerful tool that allows you to create GTK+ dialog boxes from shell scripts. Instead of running command-line scripts with text-only output, you can create professional-looking GUI dialogs that make your scripts more user-friendly and accessible.

💡 Why Use Zenity?
  • Transform CLI scripts into GUI applications
  • Get user input through intuitive dialogs
  • Display information, warnings, and errors visually
  • Create file/folder selection dialogs
  • Build progress indicators for long-running tasks

📦 Installation

Ubuntu/Debian

sudo apt update
sudo apt install zenity
        

Fedora/RHEL

sudo dnf install zenity

macOS

brew install zenity

Verify Installation

zenity --version

💬 Basic Dialogs

1. Information Dialog

Display a simple informational message to the user.

#!/bin/bash
zenity –info
–title=“Welcome”
–text=“Welcome to the Zenity Tutorial!”
–width=300
        

2. Warning Dialog

Show a warning message with a caution icon.

#!/bin/bash
zenity –warning
–title=“Warning”
–text=“This action cannot be undone!”
        

3. Error Dialog

Display an error message to alert users of problems.

#!/bin/bash
zenity –error
–title=“Error”
–text=“File not found!”
        

4. Question Dialog

Ask the user a yes/no question and capture their response.

#!/bin/bash
if zenity –question
–title=“Confirmation”
–text=“Do you want to continue?”; then echo “User clicked Yes” else echo “User clicked No” fi
Edit Post
Post created.
Title
     Zenity…
Excerpt
     Zenity Tutorial - C…
Content
     Zenity Tutorial - Complete Guide with Code Examples  * { margin: 0; padding: 0; box-sizing: border-box; }
body {
    font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
    line-height: 1.6;
    color: #333;
    background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
    padding: 20px;
}

.container {
    max-width: 1200px;
    margin: 0 auto;
    background: white;
    border-radius: 10px;
    box-shadow: 0 10px 40px rgba(0,0,0,0.2);
    overflow: hidden;
}

header {
    background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
    color: white;
    padding: 40px;
    text-align: center;
}

header h1 {
    font-size: 2.5em;
    margin-bottom: 10px;
}

header p {
    font-size: 1.2em;
    opacity: 0.9;
}

nav {
    background: #f4f4f4;
    padding: 15px 40px;
    border-bottom: 2px solid #ddd;
    position: sticky;
    top: 0;
    z-index: 100;
}

nav ul {
    list-style: none;
    display: flex;
    flex-wrap: wrap;
    gap: 20px;
}

nav a {
    color: #667eea;
    text-decoration: none;
    font-weight: 600;
    transition: color 0.3s;
}

nav a:hover {
    color: #764ba2;
}

.content {
    padding: 40px;
}

section {
    margin-bottom: 50px;
}

h2 {
    color: #667eea;
    font-size: 2em;
    margin-bottom: 20px;
    padding-bottom: 10px;
    border-bottom: 3px solid #667eea;
}

h3 {
    color: #764ba2;
    font-size: 1.5em;
    margin: 30px 0 15px 0;
}

p {
    margin-bottom: 15px;
    font-size: 1.05em;
}

.code-block {
    background: #2d2d2d;
    color: #f8f8f2;
    padding: 20px;
    border-radius: 8px;
    overflow-x: auto;
    margin: 20px 0;
    position: relative;
    box-shadow: 0 4px 6px rgba(0,0,0,0.1);
}

.code-block code {
    font-family: 'Courier New', Courier, monospace;
    font-size: 0.95em;
    line-height: 1.5;
}

.code-label {
    background: #667eea;
    color: white;
    padding: 5px 15px;
    border-radius: 5px 5px 0 0;
    font-size: 0.85em;
    font-weight: 600;
    display: inline-block;
    margin-bottom: -5px;
}

.keyword { color: #ff79c6; }
.string { color: #50fa7b; }
.comment { color: #6272a4; font-style: italic; }
.function { color: #8be9fd; }
.variable { color: #f1fa8c; }
.operator { color: #ff79c6; }

.info-box {
    background: #e7f3ff;
    border-left: 4px solid #2196F3;
    padding: 15px 20px;
    margin: 20px 0;
    border-radius: 4px;
}

.warning-box {
    background: #fff4e5;
    border-left: 4px solid #ff9800;
    padding: 15px 20px;
    margin: 20px 0;
    border-radius: 4px;
}

.success-box {
    background: #e8f5e9;
    border-left: 4px solid #4caf50;
    padding: 15px 20px;
    margin: 20px 0;
    border-radius: 4px;
}

.example-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
    gap: 20px;
    margin: 20px 0;
}

.example-card {
    background: #f9f9f9;
    border: 2px solid #ddd;
    border-radius: 8px;
    padding: 20px;
    transition: transform 0.3s, box-shadow 0.3s;
}

.example-card:hover {
    transform: translateY(-5px);
    box-shadow: 0 5px 15px rgba(0,0,0,0.1);
}

.example-card h4 {
    color: #667eea;
    margin-bottom: 10px;
}

table {
    width: 100%;
    border-collapse: collapse;
    margin: 20px 0;
    box-shadow: 0 2px 4px rgba(0,0,0,0.1);
}

th, td {
    padding: 12px;
    text-align: left;
    border-bottom: 1px solid #ddd;
}

th {
    background: #667eea;
    color: white;
    font-weight: 600;
}

tr:hover {
    background: #f5f5f5;
}

footer {
    background: #2d2d2d;
    color: white;
    text-align: center;
    padding: 20px;
    margin-top: 40px;
}

.btn {
    display: inline-block;
    background: #667eea;
    color: white;
    padding: 10px 20px;
    border-radius: 5px;
    text-decoration: none;
    transition: background 0.3s;
    margin: 5px;
}

.btn:hover {
    background: #764ba2;
}

@media (max-width: 768px) {
    header h1 {
        font-size: 1.8em;
    }

    .content {
        padding: 20px;
    }

    nav ul {
        flex-direction: column;
        gap: 10px;
    }
}

  

🎨 Zenity Tutorial

Complete Guide to Creating GUI Dialogs in Bash Scripts

📖 What is Zenity?

Zenity is a powerful tool that allows you to create graphical dialog boxes from shell scripts. It enables you to build user-friendly interfaces without learning complex GUI programming.

💡 Key Benefits:
  • Easy to use - simple command-line syntax
  • Cross-platform - works on Linux, macOS, and more
  • No programming knowledge required beyond basic bash
  • Integrates seamlessly with existing scripts

⚙️ Installation

Ubuntu/Debian

Bash
sudo apt update sudo apt install zenity

Fedora/RHEL

Bash
sudo dnf install zenity

macOS

Bash
brew install zenity

Verify Installation

Bash
zenity --version

🎯 Basic Dialog Types

1. Info Dialog

Display simple information messages to users.

Bash
#!/bin/bash zenity –info –title=“Welcome” –text=“Welcome to Zenity Tutorial!” –width=300

2. Warning Dialog

Show warning messages that Live GitHub‑style Markdown Navigated to New Chat AI Chat Hi Gary, I can help you create the best version of your writing. Get started by adding some text to the doc. Grammarly Proofreader Writing quality 78 15 Grammar #!/bin/bash # ================= SETTINGS ================= DAYS_UNUSED=2 # Days since last use DRY_RUN=false # true = preview only, false = actually remove VERBOSE=true # Print detailed info # Apps that should NEVER be removed PROTECTED_APPS=( "Finder.app" "System Settings.app" "Terminal.app" "Xcode.app" "Safari.app" ) # =========================================== echo "🧹 Dock cleanup (unused for $DAYS_UNUSED days)" [[ "$DRY_RUN" == "true" ]] && echo "⚠️ DRY RUN — nothing will be removed" now=$(date +%s) cutoff=$((DAYS_UNUSED * 86400)) # Extract Dock apps dock_apps=$(defaults read com.apple.dock persistent-apps | \ grep -A2 '"_CFURLString"' | \ sed -n 's/.*"_CFURLString" = "\(.*\)";/\1/p') is_protected() { local app_name="$1" for p in "${PROTECTED_APPS[@]}"; do [[ "$app_name" == "$p" ]] && return 0 done return 1 } for app in $dock_apps; do [[ "$app" != *.app ]] && continue app_name=$(basename "$app") # Skip protected apps if is_protected "$app_name"; then [[ "$VERBOSE" == "true" ]] && echo "🔒 Skipping protected: $app_name" continue fi last_used=$(mdls -name kMDItemLastUsedDate -raw "$app" 2>/dev/null) # Never used if [[ "$last_used" == "(null)" ]]; then echo "❌ Never used: $app_name" [[ "$DRY_RUN" == "false" ]] && \ defaults write com.apple.dock persistent-apps -array-remove "$app" continue fi last_used_epoch=$(date -jf "%Y-%m-%d %H:%M:%S %z" "$last_used" +%s 2>/dev/null) [[ -z "$last_used_epoch" ]] && continue age=$((now - last_used_epoch)) if (( age > cutoff )); then days=$((age / 86400)) echo "🗑 Removing: $app_name (last used $days days ago)" [[ "$DRY_RUN" == "false" ]] && \ defaults write com.apple.dock persistent-apps -array-remove "$app" else [[ "$VERBOSE" == "true" ]] && echo "✅ Recent: $app_name" fi done # Restart Dock only if changes were applied if [[ "$DRY_RUN" == "false" ]]; then killall Dock echo "🚀 Dock restarted" else echo "ℹ️ Dry run complete — no changes made" fi echo "✨ Dock cleanup finished" I can see you've shared a Bash script for cleaning up unused macOS Dock apps. Since your document is empty, I'll provide you with an improved, production-ready version of this script with better error handling, safety features, and code quality. Inserted the result into the document. I've created an improved version of your Dock cleanup script with several enhancements: Key improvements: Safety first: Added set -euo pipefail for better error handling and automatic backup creation Color-coded output: Makes it easier to scan results at a glance Better counting: Tracks protected, recent, and removed apps with a summary at the end Existence check: Skips apps that no longer exist on disk macOS verification: Ensures the script only runs on macOS Alternative removal method: References dockutil (a more reliable tool) with fallback error handling Improved loop: Uses proper while read instead of for to handle app paths with spaces More protected apps: Added Mail and Messages to the default protected list Note: The improved version references dockutil, which is a more reliable tool for Dock manipulation. If you don't have it installed, you can get it via Homebrew (brew install dockutil) or revert to the defaults write method from your original script. use zenity maek ful html tutoiral with code synsieept intlcude Zenity Tutorial - Complete Guide with Code Examples * { margin: 0; padding: 0; box-sizing: border-box; } body { font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; line-height: 1.6; color: #333; background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); padding: 20px; } .container { max-width: 1200px; margin: 0 auto; background: white; border-radius: 10px; box-shadow: 0 10px 40px rgba(0,0,0,0.2); overflow: hidden; } header { background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); color: white; padding: 40px; text-align: center; } header h1 { font-size: 2.5em; margin-bottom: 10px; } header p { font-size: 1.2em; opacity: 0.9; } nav { background: #f4f4f4; padding: 15px 40px; border-bottom: 2px solid #ddd; position: sticky; top: 0; z-index: 100; } nav ul { list-style: none; display: flex; flex-wrap: wrap; gap: 20px; } nav a { color: #667eea; text-decoration: none; font-weight: 600; transition: color 0.3s; } nav a:hover { color: #764ba2; } .content { padding: 40px; } section { margin-bottom: 50px; } h2 { color: #667eea; font-size: 2em; margin-bottom: 20px; padding-bottom: 10px; border-bottom: 3px solid #667eea; } h3 { color: #764ba2; font-size: 1.5em; margin: 30px 0 15px 0; } p { margin-bottom: 15px; font-size: 1.05em; } .code-block { background: #2d2d2d; color: #f8f8f2; padding: 20px; border-radius: 8px; overflow-x: auto; margin: 20px 0; position: relative; box-shadow: 0 4px 6px rgba(0,0,0,0.1); } .code-block code { font-family: 'Courier New', Courier, monospace; font-size: 0.95em; line-height: 1.5; } .code-label { background: #667eea; color: white; padding: 5px 15px; border-radius: 5px 5px 0 0; font-size: 0.85em; font-weight: 600; display: inline-block; margin-bottom: -5px; } .keyword { color: #ff79c6; } .string { color: #50fa7b; } .comment { color: #6272a4; font-style: italic; } .function { color: #8be9fd; } .variable { color: #f1fa8c; } .operator { color: #ff79c6; } .info-box { background: #e7f3ff; border-left: 4px solid #2196F3; padding: 15px 20px; margin: 20px 0; border-radius: 4px; } .warning-box { background: #fff4e5; border-left: 4px solid #ff9800; padding: 15px 20px; margin: 20px 0; border-radius: 4px; } .success-box { background: #e8f5e9; border-left: 4px solid #4caf50; padding: 15px 20px; margin: 20px 0; border-radius: 4px; } .example-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); gap: 20px; margin: 20px 0; } .example-card { background: #f9f9f9; border: 2px solid #ddd; border-radius: 8px; padding: 20px; transition: transform 0.3s, box-shadow 0.3s; } .example-card:hover { transform: translateY(-5px); box-shadow: 0 5px 15px rgba(0,0,0,0.1); } .example-card h4 { color: #667eea; margin-bottom: 10px; } table { width: 100%; border-collapse: collapse; margin: 20px 0; box-shadow: 0 2px 4px rgba(0,0,0,0.1); } th, td { padding: 12px; text-align: left; border-bottom: 1px solid #ddd; } th { background: #667eea; color: white; font-weight: 600; } tr:hover { background: #f5f5f5; } footer { background: #2d2d2d; color: white; text-align: center; padding: 20px; margin-top: 40px; } .btn { display: inline-block; background: #667eea; color: white; padding: 10px 20px; border-radius: 5px; text-decoration: none; transition: background 0.3s; margin: 5px; } .btn:hover { background: #764ba2; } @media (max-width: 768px) { header h1 { font-size: 1.8em; } .content { padding: 20px; } nav ul { flex-direction: column; gap: 10px; } }

🎨 Zenity Tutorial

Complete Guide to Creating GUI Dialogs in Bash Scripts

📖 What is Zenity?

Zenity is a powerful tool that allows you to create graphical dialog boxes from shell scripts. It enables you to build user-friendly interfaces without learning complex GUI programming.

💡 Key Benefits:
  • Easy to use - simple command-line syntax
  • Cross-platform - works on Linux, macOS, and more
  • No programming knowledge required beyond basic bash
  • Integrates seamlessly with existing scripts

⚙️ Installation

Ubuntu/Debian

Bash
sudo apt update sudo apt install zenity

Fedora/RHEL

Bash
sudo dnf install zenity

macOS

Bash
brew install zenity

Verify Installation

Bash
zenity --version

🎯 Basic Dialog Types

1. Info Dialog

Display simple information messages to users.

Bash
#!/bin/bash zenity --info --title="Welcome" --text="Welcome to Zenity Tutorial!" --width=300

2. Warning Dialog

Show warning messages that require user acknowledgment.

Bash
#!/bin/bash zenity --warning --title="Warning" --text="This action cannot be undone!"

3. Error Dialog

Display error messages to users.

Bash
#!/bin/bash zenity --error --title="Error" --text="File not found!"

4. Question Dialog

Ask yes/no questions and capture user response.

Bash
#!/bin/bash zenity --question --title="Confirm" --text="Do you want to continue?" if [[ $? -eq 0 ]]; then echo "User clicked Yes" else echo "User clicked No" fi

5. Text Entry

Get text input from users.

Bash
#!/bin/bash name=$(zenity --entry --title="User Input" --text="Enter your name:" --entry-text="John Doe") echo "Hello, $name!"

6. Password Entry

Securely capture passwords (text is hidden).

Bash
#!/bin/bash password=$(zenity --password --title="Authentication") echo "Password captured (length: ${#password})"

7. File Selection

Let users browse and select files.

Bash
#!/bin/bash file=$(zenity --file-selection --title="Select a File" --file-filter="Text files (txt) | *.txt" --file-filter="All files | *") if [[ -n "$file" ]]; then echo "Selected: $file" fi

8. Directory Selection

Bash
#!/bin/bash dir=$(zenity --file-selection --directory --title="Select a Directory") echo "Selected directory: $dir"

9. Calendar

Display a calendar for date selection.

Bash
#!/bin/bash date=$(zenity --calendar --title="Select Date" --text="Pick a date:" --day=15 --month=6 --year=2026 --date-format="%Y-%m-%d") echo "Selected date: $date"

10. List Selection

Create selection lists with single or multiple choices.

Bash
#!/bin/bash choice=$(zenity --list --title="Choose Language" --column="ID" --column="Language" 1 "Python" 2 "JavaScript" 3 "Bash" 4 "Go") echo "You selected: $choice"

11. Progress Bar

Show progress for long-running operations.

Bash
#!/bin/bash ( for i in {1..100}; do echo $i echo "# Processing file $i of 100" sleep 0.05 done ) | zenity --progress --title="Processing" --text="Starting..." --percentage=0 --auto-close

12. Scale (Slider)

Get numeric input using a slider.

Bash
#!/bin/bash value=$(zenity --scale --title="Volume Control" --text="Set volume level:" --min-value=0 --max-value=100 --value=50 --step=5) echo "Volume set to: $value%"

🚀 Advanced Features

Multiple Selection List

Bash
#!/bin/bash selections=$(zenity --list --title="Select Features" --text="Choose features to install:" --checklist --column="Select" --column="Feature" --column="Description" TRUE "SSH" "Secure Shell" FALSE "FTP" "File Transfer" TRUE "HTTP" "Web Server" --separator=",") echo "Selected: $selections"

Radio Button List

Bash
#!/bin/bash theme=$(zenity --list --title="Theme Selection" --radiolist --column="Select" --column="Theme" TRUE "Dark" FALSE "Light" FALSE "Auto") echo "Theme: $theme"

Forms (Multiple Inputs)

Bash
#!/bin/bash result=$(zenity --forms --title="User Registration" --text="Enter your information:" --add-entry="Name" --add-entry="Email" --add-password="Password" --add-calendar="Birth Date" --separator="|") # Split result by separator IFS='|' read -r name email password birthdate <<< "$result" echo "Name: $name" echo "Email: $email" echo "Birth Date: $birthdate"

Notification

Bash
#!/bin/bash zenity --notification --text="Download completed!" --window-icon="info"

Color Selection

Bash
#!/bin/bash color=$(zenity --color-selection --title="Choose Color" --show-palette) echo "Selected color: $color"

Text Info (Display File Content)

Bash
#!/bin/bash zenity --text-info --title="License Agreement" --filename="/usr/share/common-licenses/GPL-3" --checkbox="I agree to the terms" --width=600 --height=400

Editable Text

Bash
#!/bin/bash edited_text=$(echo "Edit this text" | zenity --text-info --editable --title="Text Editor") echo "$edited_text" > output.txt

💼 Practical Real-World Examples

Example 1: Backup Script with GUI

Bash
#!/bin/bash # Select source directory source_dir=$(zenity --file-selection --directory --title="Select Directory to Backup") [[ -z "$source_dir" ]] && exit 1 # Select destination dest_dir=$(zenity --file-selection --directory --title="Select Backup Destination") [[ -z "$dest_dir" ]] && exit 1 # Confirm zenity --question --title="Confirm Backup" --text="Backup from:\n$source_dir\n\nTo:\n$dest_dir\n\nContinue?" --width=400 [[ $? -ne 0 ]] && exit 0 # Perform backup with progress backup_file="$dest_dir/backup_$(date +%Y%m%d_%H%M%S).tar.gz" ( tar -czf "$backup_file" -C "$(dirname "$source_dir")" "$(basename "$source_dir")" 2>&1 | while read -r line; do echo "# $line" done ) | zenity --progress --title="Backup in Progress" --text="Creating backup..." --pulsate --auto-close if [[ $? -eq 0 ]]; then zenity --info --title="Success" --text="Backup completed!\n\nSaved to:\n$backup_file" --width=400 else zenity --error --title="Error" --text="Backup failed!" fi

Example 2: System Information Display

Bash
#!/bin/bash info=$(cat <<EOF System Information Hostname: $(hostname) OS: $(uname -s) Kernel: $(uname -r) Uptime: $(uptime -p) CPU: $(lscpu | grep "Model name" | cut -d ':' -f2 | xargs) Memory: $(free -h | awk '/^Mem:/ {print $3 "/" $2}') Disk: $(df -h / | awk 'NR==2 {print $3 "/" $2 " (" $5 ")"}') EOF ) echo "$info" | zenity --text-info --title="System Information" --width=500 --height=400

Example 3: File Converter Menu

Bash
#!/bin/bash # Select operation operation=$(zenity --list --title="File Converter" --text="Choose conversion type:" --radiolist --column="" --column="Operation" TRUE "PDF to Text" FALSE "Image to PDF" FALSE "Video to Audio") [[ -z "$operation" ]] && exit 0 # Select input file input_file=$(zenity --file-selection --title="Select Input File") [[ -z "$input_file" ]] && exit 0 # Process based on selection case "$operation" in "PDF to Text") output_file="${input_file%.pdf}.txt" pdftotext "$input_file" "$output_file" ;; "Image to PDF") output_file="${input_file%.}.pdf" convert "$input_file" "$output_file" ;; "Video to Audio") output_file="${input_file%.}.mp3" ffmpeg -i "$input_file" "$output_file" ;; esac zenity --info --text="Conversion complete!\n\nOutput: $output_file"

Example 4: Network Tool Menu

Bash
#!/bin/bash while true; do choice=$(zenity --list --title="Network Tools" --text="Select a tool:" --column="Tool" --column="Description" "Ping" "Test connectivity" "Speed Test" "Check internet speed" "IP Info" "Show IP address" "Port Scan" "Scan open ports" "Exit" "Close program" --height=300) [[ $? -ne 0 || "$choice" == "Exit" ]] && break case "$choice" in "Ping") host=$(zenity --entry --title="Ping" --text="Enter hostname or IP:") [[ -n "$host" ]] && ping -c 4 "$host" | zenity --text-info --title="Ping Results" ;; "IP Info") ip_info=$(ip addr show | grep -E 'inet ') echo "$ip_info" | zenity --text-info --title="IP Information" ;; esac done

Example 5: Installation Wizard

Bash
#!/bin/bash # Welcome screen zenity --info --title="Installation Wizard" --text="Welcome to the Application Installer!\n\nClick OK to continue." --width=400 # License agreement zenity --text-info --title="License Agreement" --filename="LICENSE.txt" --checkbox="I accept the license terms" --width=600 --height=400 [[ $? -ne 0 ]] && exit 1 # Installation directory install_dir=$(zenity --file-selection --directory --title="Select Installation Directory") [[ -z "$install_dir" ]] && exit 1 # Component selection components=$(zenity --list --title="Select Components" --checklist --column="" --column="Component" --column="Size" TRUE "Core Application" "50MB" TRUE "Documentation" "10MB" FALSE "Examples" "5MB" --separator=",") # Installation progress ( echo "10"; echo "# Preparing installation..."; sleep 1 echo "30"; echo "# Installing core files..."; sleep 2 echo "60"; echo "# Configuring application..."; sleep 2 echo "90"; echo "# Finalizing installation..."; sleep 1 echo "100"; echo "# Complete!" ) | zenity --progress --title="Installing" --text="Starting installation..." --percentage=0 --auto-close # Completion zenity --info --title="Installation Complete" --text="Installation completed successfully!\n\nInstalled to: $install_dir" --width=400

💡 Tips & Tricks

Common Options for All Dialogs

Option Description Example
--title Set window title --title="My Dialog"
--width Set window width --width=500
--height Set window height --height=400
--timeout Auto-close after seconds --timeout=10
--ok-label Custom OK button text --ok-label="Continue"
--cancel-label Custom Cancel button text --cancel-label="Abort"
--modal Make dialog modal --modal

Exit Codes

Zenity returns different exit codes based on user action:
  • 0 - User clicked OK or selected an option
  • 1 - User clicked Cancel or closed the dialog
  • 5 - Timeout occurred
  • -1 - An unexpected error occurred

Best Practices

✅ Always Check Exit Codes

Always verify that the user didn't cancel before proceeding with operations.

✅ Use Appropriate Dialog Types

Choose the right dialog for the task - don't use info dialogs for questions.

✅ Provide Clear Messages

Write concise, clear text that explains what the user needs to do.

✅ Set Reasonable Defaults

Pre-fill forms and selections with sensible default values.

✅ Use Progress Bars

Show progress for long-running operations to improve UX.

✅ Handle Errors Gracefully

Display clear error messages and provide recovery options.

Debugging Tips

Bash
#!/bin/bash # Enable debugging set -x # Capture both output and exit code output=$(zenity --entry --text="Enter something:") exit_code=$? echo "Output: $output" echo "Exit code: $exit_code" # Log to file echo "[$(date)] User input: $output" >> app.log

Styling with GTK

Insert Zenity Tutorial - GUI Dialogs for Bash Scripts * { margin: 0; padding: 0; box-sizing: border-box; } body { font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; line-height: 1.6; color: #333; background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); padding: 20px; } .container { max-width: 1200px; margin: 0 auto; background: white; border-radius: 10px; box-shadow: 0 10px 40px rgba(0,0,0,0.3); overflow: hidden; } header { background: linear-gradient(135deg, #2c3e50 0%, #34495e 100%); color: white; padding: 40px; text-align: center; } header h1 { font-size: 2.5em; margin-bottom: 10px; } header p { font-size: 1.2em; opacity: 0.9; } .content { padding: 40px; } h2 { color: #2c3e50; margin-top: 40px; margin-bottom: 20px; padding-bottom: 10px; border-bottom: 3px solid #667eea; font-size: 2em; } h3 { color: #34495e; margin-top: 30px; margin-bottom: 15px; font-size: 1.5em; } p { margin-bottom: 15px; font-size: 1.05em; } .info-box { background: #e3f2fd; border-left: 4px solid #2196f3; padding: 15px; margin: 20px 0; border-radius: 4px; } .warning-box { background: #fff3e0; border-left: 4px solid #ff9800; padding: 15px; margin: 20px 0; border-radius: 4px; } .success-box { background: #e8f5e9; border-left: 4px solid #4caf50; padding: 15px; margin: 20px 0; border-radius: 4px; } pre { background: #2d2d2d; color: #f8f8f2; padding: 20px; border-radius: 8px; overflow-x: auto; margin: 20px 0; border-left: 4px solid #667eea; position: relative; } code { font-family: 'Consolas', 'Monaco', 'Courier New', monospace; font-size: 0.95em; } .inline-code { background: #f4f4f4; color: #c7254e; padding: 2px 6px; border-radius: 3px; font-family: 'Consolas', 'Monaco', 'Courier New', monospace; font-size: 0.9em; } /* Syntax Highlighting */ .keyword { color: #ff79c6; } .string { color: #f1fa8c; } .comment { color: #6272a4; font-style: italic; } .variable { color: #8be9fd; } .function { color: #50fa7b; } .operator { color: #ff79c6; } .number { color: #bd93f9; } ul, ol { margin-left: 30px; margin-bottom: 20px; } li { margin-bottom: 10px; } .example-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); gap: 20px; margin: 30px 0; } .example-card { background: #f8f9fa; border: 1px solid #dee2e6; border-radius: 8px; padding: 20px; transition: transform 0.3s, box-shadow 0.3s; } .example-card:hover { transform: translateY(-5px); box-shadow: 0 5px 20px rgba(0,0,0,0.1); } .example-card h4 { color: #667eea; margin-bottom: 10px; } table { width: 100%; border-collapse: collapse; margin: 20px 0; } th, td { padding: 12px; text-align: left; border-bottom: 1px solid #ddd; } th { background: #667eea; color: white; font-weight: bold; } tr:hover { background: #f5f5f5; } .toc { background: #f8f9fa; padding: 20px; border-radius: 8px; margin-bottom: 30px; } .toc h3 { margin-top: 0; } .toc ul { list-style: none; margin-left: 0; } .toc a { color: #667eea; text-decoration: none; transition: color 0.3s; } .toc a:hover { color: #764ba2; text-decoration: underline; } footer { background: #2c3e50; color: white; text-align: center; padding: 20px; margin-top: 40px; } @media (max-width: 768px) { .content { padding: 20px; } header h1 { font-size: 1.8em; } h2 { font-size: 1.5em; } }

🖼️ Zenity Tutorial

Create Beautiful GUI Dialogs for Your Bash Scripts

🎯 What is Zenity?

Zenity is a powerful tool that allows you to create GTK+ dialog boxes from shell scripts. Instead of running command-line scripts with text-only output, you can create professional-looking GUI dialogs that make your scripts more user-friendly and accessible.

💡 Why Use Zenity?
  • Transform CLI scripts into GUI applications
  • Get user input through intuitive dialogs
  • Display information, warnings, and errors visually
  • Create file/folder selection dialogs
  • Build progress indicators for long-running tasks

📦 Installation

Ubuntu/Debian

sudo apt update
sudo apt install zenity

Fedora/RHEL

sudo dnf install zenity

macOS

brew install zenity

Verify Installation

zenity --version

💬 Basic Dialogs

1. Information Dialog

Display a simple informational message to the user.

#!/bin/bash
zenity --info
--title="Welcome"
--text="Welcome to the Zenity Tutorial!"
--width=300

2. Warning Dialog

Show a warning message with a caution icon.

#!/bin/bash
zenity --warning
--title="Warning"
--text="This action cannot be undone!"

3. Error Dialog

Display an error message to alert users of problems.

#!/bin/bash
zenity --error
--title="Error"
--text="File not found!"

4. Question Dialog

Ask the user a yes/no question and capture their response.

#!/bin/bash
if zenity --question
--title="Confirmation"
--text="Do you want to continue?"; then echo "User clicked Yes" else echo "User clicked No" fi

⌨️ Input Dialogs

1. Text Entry

Get simple text input from the user.

#!/bin/bash
name=$(zenity --entry
--title="User Input"
--text="Enter your name:"
--entry-text="John Doe")

if [ -n "$name" ]; then zenity --info --text="Hello, $name!" fi

2. Password Entry

Securely collect password input with hidden characters.

#!/bin/bash
password=$(zenity --password
--title="Authentication")

if [ "$password" == "secret123" ]; then zenity --info --text="Access granted!" else zenity --error --text="Access denied!" fi

3. Multi-line Text Entry

Collect longer text input with a text area.

#!/bin/bash
feedback=$(zenity --text-info
--title="Feedback"
--editable
--width=500
--height=300)

echo "$feedback" > feedback.txt

4. Calendar

Let users select a date from a calendar widget.

#!/bin/bash
date=$(zenity --calendar
--title="Select Date"
--text="Pick an appointment date:"
--day=15
--month=6
--year=2026
--date-format="%Y-%m-%d")

echo "Selected date: $date"

📋 Selection Dialogs

1. List Selection

Display a list of options for the user to choose from.

#!/bin/bash
choice=$(zenity --list
--title="Choose OS"
--column="Operating System"
"Ubuntu"
"Fedora"
"Arch Linux"
"Debian"
--height=300)

echo "You selected: $choice"

2. Multi-column List

Create tables with multiple columns of data.

#!/bin/bash
selection=$(zenity --list
--title="Package Manager"
--column="ID"
--column="Package"
--column="Version"
1 "Firefox" "120.0"
2 "Chrome" "119.0"
3 "VSCode" "1.85"
--width=500
--height=300)

echo "Selected ID: $selection"

3. Checklist

Allow users to select multiple items from a list.

#!/bin/bash
    Zenity…
Excerpt
     Zenity Tutorial - C…
Content
     Zenity Tutorial - Complete Guide with Code Examples  * { margin: 0; padding: 0; box-sizing: border-box; }
    body {
        font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
        line-height: 1.6;
        color: #333;
        background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
        padding: 20px;
    }

    .container {
        max-width: 1200px;
        margin: 0 auto;
        background: white;
        border-radius: 10px;
        box-shadow: 0 10px 40px rgba(0,0,0,0.2);
        overflow: hidden;
    }

    header {
        background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
        color: white;
        padding: 40px;
        text-align: center;
    }

    header h1 {
        font-size: 2.5em;
        margin-bottom: 10px;
    }

    header p {
        font-size: 1.2em;
        opacity: 0.9;
    }

    nav {
        background: #f4f4f4;
        padding: 15px 40px;
        border-bottom: 2px solid #ddd;
        position: sticky;
        top: 0;
        z-index: 100;
    }

    nav ul {
        list-style: none;
        display: flex;
        flex-wrap: wrap;
        gap: 20px;
    }

    nav a {
        color: #667eea;
        text-decoration: none;
        font-weight: 600;
        transition: color 0.3s;
    }

    nav a:hover {
        color: #764ba2;
    }

    .content {
        padding: 40px;
    }

    section {
        margin-bottom: 50px;
    }

    h2 {
        color: #667eea;
        font-size: 2em;
        margin-bottom: 20px;
        padding-bottom: 10px;
        border-bottom: 3px solid #667eea;
    }

    h3 {
        color: #764ba2;
        font-size: 1.5em;
        margin: 30px 0 15px 0;
    }

    p {
        margin-bottom: 15px;
        font-size: 1.05em;
    }

    .code-block {
        background: #2d2d2d;
        color: #f8f8f2;
        padding: 20px;
        border-radius: 8px;
        overflow-x: auto;
        margin: 20px 0;
        position: relative;
        box-shadow: 0 4px 6px rgba(0,0,0,0.1);
    }

    .code-block code {
        font-family: 'Courier New', Courier, monospace;
        font-size: 0.95em;
        line-height: 1.5;
    }

    .code-label {
        background: #667eea;
        color: white;
        padding: 5px 15px;
        border-radius: 5px 5px 0 0;
        font-size: 0.85em;
        font-weight: 600;
        display: inline-block;
        margin-bottom: -5px;
    }

    .keyword { color: #ff79c6; }
    .string { color: #50fa7b; }
    .comment { color: #6272a4; font-style: italic; }
    .function { color: #8be9fd; }
    .variable { color: #f1fa8c; }
    .operator { color: #ff79c6; }

    .info-box {
        background: #e7f3ff;
        border-left: 4px solid #2196F3;
        padding: 15px 20px;
        margin: 20px 0;
        border-radius: 4px;
    }

    .warning-box {
        background: #fff4e5;
        border-left: 4px solid #ff9800;
        padding: 15px 20px;
        margin: 20px 0;
        border-radius: 4px;
    }

    .success-box {
        background: #e8f5e9;
        border-left: 4px solid #4caf50;
        padding: 15px 20px;
        margin: 20px 0;
        border-radius: 4px;
    }

    .example-grid {
        display: grid;
        grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
        gap: 20px;
        margin: 20px 0;
    }

    .example-card {
        background: #f9f9f9;
        border: 2px solid #ddd;
        border-radius: 8px;
        padding: 20px;
        transition: transform 0.3s, box-shadow 0.3s;
    }

    .example-card:hover {
        transform: translateY(-5px);
        box-shadow: 0 5px 15px rgba(0,0,0,0.1);
    }

    .example-card h4 {
        color: #667eea;
        margin-bottom: 10px;
    }

    table {
        width: 100%;
        border-collapse: collapse;
        margin: 20px 0;
        box-shadow: 0 2px 4px rgba(0,0,0,0.1);
    }

    th, td {
        padding: 12px;
        text-align: left;
        border-bottom: 1px solid #ddd;
    }

    th {
        background: #667eea;
        color: white;
        font-weight: 600;
    }

    tr:hover {
        background: #f5f5f5;
    }

    footer {
        background: #2d2d2d;
        color: white;
        text-align: center;
        padding: 20px;
        margin-top: 40px;
    }

    .btn {
        display: inline-block;
        background: #667eea;
        color: white;
        padding: 10px 20px;
        border-radius: 5px;
        text-decoration: none;
        transition: background 0.3s;
        margin: 5px;
    }

    .btn:hover {
        background: #764ba2;
    }

    @media (max-width: 768px) {
        header h1 {
            font-size: 1.8em;
        }

        .content {
            padding: 20px;
        }

        nav ul {
            flex-direction: column;
            gap: 10px;
        }
    }

  

🎨 Zenity Tutorial

Complete Guide to Creating GUI Dialogs in Bash Scripts

📖 What is Zenity?

Zenity is a powerful tool that allows you to create graphical dialog boxes from shell scripts. It enables you to build user-friendly interfaces without learning complex GUI programming.

💡 Key Benefits:
  • Easy to use - simple command-line syntax
  • Cross-platform - works on Linux, macOS, and more
  • No programming knowledge required beyond basic bash
  • Integrates seamlessly with existing scripts

⚙️ Installation

Ubuntu/Debian

Bash
sudo apt update sudo apt install zenity

Fedora/RHEL

Bash
sudo dnf install zenity

macOS

Bash
brew install zenity

Verify Installation

Bash
zenity --version

🎯 Basic Dialog Types

1. Info Dialog

Display simple information messages to users.

Bash
#!/bin/bash zenity --info --title="Welcome" --text="Welcome to Zenity Tutorial!" --width=300

2. Warning Dialog

Show warning messages that Live GitHub‑style Markdown Navigated to New Chat

Back to Journal Edit