System Report
The automated backup process has completed successfully.
- Start time: '"$(date)"'
- Files processed: 1,247
- Total size: 2.3 GB
Status: SUCCESS
' send_html_email "admin@example.com" "Backup Report" "$html_content" ``` Email Notification Functions Create reusable functions for different types of email notifications: ```bash #!/bin/bash Configuration EMAIL_FROM="noreply@yourdomain.com" EMAIL_ADMIN="admin@yourdomain.com" Success notification send_success_email() { local operation="$1" local details="$2" mail -s "SUCCESS: $operation" "$EMAIL_ADMIN" << EOF Operation: $operation Status: Completed successfully Time: $(date) Details: $details This is an automated message from $(hostname). EOF } Error notification send_error_email() { local operation="$1" local error_message="$2" local log_file="$3" { echo "Operation: $operation" echo "Status: FAILED" echo "Time: $(date)" echo "Error: $error_message" echo "" echo "Recent log entries:" if [[ -f "$log_file" ]]; then tail -20 "$log_file" fi } | mail -s "ERROR: $operation" "$EMAIL_ADMIN" } Usage examples send_success_email "Database Backup" "Backup size: 500MB, Duration: 5 minutes" send_error_email "File Sync" "Permission denied" "/var/log/sync.log" ``` System Log Notifications Integrating with system logs provides persistent notification records and enables centralized monitoring. Using logger Command The `logger` command sends messages to the system log: ```bash #!/bin/bash Basic logging logger "Script execution started" Logging with priority and tag logger -p user.info -t "backup-script" "Backup process initiated" Logging with different priorities logger -p user.debug -t "debug-script" "Debug information" logger -p user.warning -t "warning-script" "Warning condition detected" logger -p user.err -t "error-script" "Error occurred during processing" ``` Custom Log Files Create custom log files for specific applications: ```bash #!/bin/bash LOG_FILE="/var/log/custom-script.log" Logging function log_message() { local level="$1" local message="$2" local timestamp=$(date '+%Y-%m-%d %H:%M:%S') echo "[$timestamp] [$level] $message" >> "$LOG_FILE" # Also send to syslog logger -t "custom-script" "[$level] $message" # Send notification for critical messages if [[ "$level" == "ERROR" ]]; then notify-send -u critical "Script Error" "$message" fi } Usage examples log_message "INFO" "Script started successfully" log_message "WARNING" "Disk space is getting low" log_message "ERROR" "Failed to connect to database" ``` Log Rotation and Management Implement log rotation to manage log file sizes: ```bash #!/bin/bash LOG_FILE="/var/log/my-script.log" MAX_SIZE=10485760 # 10MB in bytes Function to rotate logs rotate_log() { if [[ -f "$LOG_FILE" ]]; then local file_size=$(stat -f%z "$LOG_FILE" 2>/dev/null || stat -c%s "$LOG_FILE" 2>/dev/null) if [[ $file_size -gt $MAX_SIZE ]]; then mv "$LOG_FILE" "${LOG_FILE}.old" touch "$LOG_FILE" chmod 644 "$LOG_FILE" logger -t "log-rotation" "Log file rotated: $LOG_FILE" fi fi } Enhanced logging function with rotation log_with_rotation() { local level="$1" local message="$2" # Rotate if necessary rotate_log # Log the message echo "[$(date '+%Y-%m-%d %H:%M:%S')] [$level] $message" >> "$LOG_FILE" } ``` Sound Notifications Audio notifications are useful for alerting users when visual notifications might be missed. Basic Sound Notifications Use system sounds for notifications: ```bash #!/bin/bash Play system beep echo -e "\a" Play system sound files paplay /usr/share/sounds/alsa/Front_Left.wav Using aplay for ALSA systems aplay /usr/share/sounds/alsa/Front_Right.wav ``` Custom Sound Notifications Implement custom sound notifications with different sounds for different events: ```bash #!/bin/bash SOUND_DIR="/usr/share/sounds" Function to play notification sounds play_notification_sound() { local event_type="$1" case "$event_type" in "success") paplay "$SOUND_DIR/freedesktop/stereo/complete.oga" 2>/dev/null || echo -e "\a" ;; "error") paplay "$SOUND_DIR/freedesktop/stereo/dialog-error.oga" 2>/dev/null || echo -e "\a\a\a" ;; "warning") paplay "$SOUND_DIR/freedesktop/stereo/dialog-warning.oga" 2>/dev/null || echo -e "\a\a" ;; *) echo -e "\a" ;; esac } Usage examples play_notification_sound "success" play_notification_sound "error" play_notification_sound "warning" ``` Text-to-Speech Notifications Use text-to-speech for spoken notifications: ```bash #!/bin/bash Install espeak for text-to-speech sudo apt-get install espeak Function for spoken notifications speak_notification() { local message="$1" local voice="${2:-en}" if command -v espeak >/dev/null 2>&1; then espeak -v "$voice" "$message" 2>/dev/null & elif command -v festival >/dev/null 2>&1; then echo "$message" | festival --tts 2>/dev/null & else echo "Text-to-speech not available" fi } Usage examples speak_notification "Backup completed successfully" speak_notification "Warning: Disk space is low" "en+f3" ``` Custom Notification Solutions For advanced use cases, you can create custom notification solutions using various tools and techniques. Zenity Dialog Notifications Zenity provides GUI dialog boxes for scripts: ```bash #!/bin/bash Information dialog zenity --info --title="Process Complete" --text="The file processing has finished successfully." Warning dialog zenity --warning --title="System Warning" --text="Disk space is running low. Please clean up unnecessary files." Error dialog with custom icon zenity --error --title="Critical Error" --text="Database connection failed. Please check your network settings." Progress dialog ( echo "10" ; sleep 1 echo "# Copying files..." ; echo "30" ; sleep 1 echo "# Processing data..." ; echo "50" ; sleep 1 echo "# Finalizing..." ; echo "100" ; sleep 1 ) | zenity --progress --title="Operation Progress" --text="Starting operation..." --percentage=0 ``` Web-based Notifications Send notifications through web services: ```bash #!/bin/bash Slack webhook notification send_slack_notification() { local webhook_url="$1" local channel="$2" local message="$3" local username="${4:-Script Bot}" curl -X POST -H 'Content-type: application/json' \ --data "{ \"channel\":\"$channel\", \"username\":\"$username\", \"text\":\"$message\" }" \ "$webhook_url" } Discord webhook notification send_discord_notification() { local webhook_url="$1" local message="$2" curl -H "Content-Type: application/json" \ -X POST \ -d "{\"content\": \"$message\"}" \ "$webhook_url" } Telegram bot notification send_telegram_notification() { local bot_token="$1" local chat_id="$2" local message="$3" curl -s -X POST "https://api.telegram.org/bot$bot_token/sendMessage" \ -d chat_id="$chat_id" \ -d text="$message" } Usage examples send_slack_notification "$SLACK_WEBHOOK" "#alerts" "Server backup completed successfully" send_discord_notification "$DISCORD_WEBHOOK" "Database maintenance finished" send_telegram_notification "$TELEGRAM_BOT_TOKEN" "$TELEGRAM_CHAT_ID" "System update completed" ``` Database Logging Store notifications in a database for historical tracking: ```bash #!/bin/bash SQLite database for notification logging DB_FILE="/var/log/notifications.db" Initialize database init_notification_db() { sqlite3 "$DB_FILE" << EOF CREATE TABLE IF NOT EXISTS notifications ( id INTEGER PRIMARY KEY AUTOINCREMENT, timestamp DATETIME DEFAULT CURRENT_TIMESTAMP, level TEXT NOT NULL, title TEXT NOT NULL, message TEXT NOT NULL, script_name TEXT, hostname TEXT DEFAULT '$(hostname)' ); EOF } Log notification to database log_notification_db() { local level="$1" local title="$2" local message="$3" local script_name="$4" sqlite3 "$DB_FILE" << EOF INSERT INTO notifications (level, title, message, script_name) VALUES ('$level', '$title', '$message', '$script_name'); EOF } Query recent notifications get_recent_notifications() { local limit="${1:-10}" sqlite3 -header -column "$DB_FILE" << EOF SELECT timestamp, level, title, message, script_name FROM notifications ORDER BY timestamp DESC LIMIT $limit; EOF } Initialize and use init_notification_db log_notification_db "INFO" "Backup Complete" "Files backed up successfully" "backup-script.sh" ``` Advanced Notification Techniques Conditional Notifications Implement smart notification logic based on conditions: ```bash #!/bin/bash NOTIFICATION_CONFIG="/etc/script-notifications.conf" Load notification preferences load_notification_config() { if [[ -f "$NOTIFICATION_CONFIG" ]]; then source "$NOTIFICATION_CONFIG" else # Default settings NOTIFY_SUCCESS=true NOTIFY_WARNING=true NOTIFY_ERROR=true QUIET_HOURS_START="22:00" QUIET_HOURS_END="08:00" NOTIFICATION_METHODS=("desktop" "email") fi } Check if current time is within quiet hours is_quiet_hours() { local current_time=$(date +%H:%M) local start_seconds=$(date -d "$QUIET_HOURS_START" +%s) local end_seconds=$(date -d "$QUIET_HOURS_END" +%s) local current_seconds=$(date -d "$current_time" +%s) if [[ $start_seconds -gt $end_seconds ]]; then # Quiet hours span midnight [[ $current_seconds -ge $start_seconds ]] || [[ $current_seconds -le $end_seconds ]] else [[ $current_seconds -ge $start_seconds ]] && [[ $current_seconds -le $end_seconds ]] fi } Smart notification function smart_notify() { local level="$1" local title="$2" local message="$3" load_notification_config # Check if this notification type is enabled case "$level" in "SUCCESS") [[ "$NOTIFY_SUCCESS" != "true" ]] && return 0 ;; "WARNING") [[ "$NOTIFY_WARNING" != "true" ]] && return 0 ;; "ERROR") [[ "$NOTIFY_ERROR" != "true" ]] && return 0 ;; esac # Skip non-critical notifications during quiet hours if is_quiet_hours && [[ "$level" != "ERROR" ]]; then return 0 fi # Send notifications via configured methods for method in "${NOTIFICATION_METHODS[@]}"; do case "$method" in "desktop") notify-send "$title" "$message" ;; "email") echo "$message" | mail -s "$title" "$EMAIL_ADMIN" ;; "sound") play_notification_sound "${level,,}" ;; esac done } ``` Notification Queuing Implement a notification queue system: ```bash #!/bin/bash NOTIFICATION_QUEUE="/tmp/notification_queue" Initialize queue init_notification_queue() { mkdir -p "$NOTIFICATION_QUEUE" } Add notification to queue queue_notification() { local priority="$1" local title="$2" local message="$3" local timestamp=$(date +%s) local queue_file="$NOTIFICATION_QUEUE/${priority}_${timestamp}_$$" cat > "$queue_file" << EOF TITLE=$title MESSAGE=$message PRIORITY=$priority TIMESTAMP=$timestamp EOF } Process notification queue process_notification_queue() { local max_notifications="${1:-5}" local processed=0 # Process notifications by priority (lower number = higher priority) for queue_file in $(ls "$NOTIFICATION_QUEUE" | sort -n | head -n "$max_notifications"); do local full_path="$NOTIFICATION_QUEUE/$queue_file" if [[ -f "$full_path" ]]; then source "$full_path" # Send the notification notify-send "$TITLE" "$MESSAGE" # Remove from queue rm "$full_path" ((processed++)) sleep 1 # Prevent notification spam fi done echo "Processed $processed notifications" } Usage init_notification_queue queue_notification "1" "Critical Error" "System failure detected" queue_notification "3" "Info" "Backup completed" queue_notification "2" "Warning" "Disk space low" process_notification_queue ``` Troubleshooting Common Issues Desktop Environment Issues Common problems with desktop notifications: ```bash #!/bin/bash Troubleshooting function for desktop notifications troubleshoot_desktop_notifications() { echo "Troubleshooting desktop notifications..." # Check if notification daemon is running if ! pgrep -x "notification-daemon\|notify-osd\|dunst" > /dev/null; then echo "ERROR: No notification daemon found running" echo "Try: sudo service notification-daemon start" fi # Check DISPLAY variable if [[ -z "$DISPLAY" ]]; then echo "ERROR: DISPLAY variable not set" echo "Try: export DISPLAY=:0" fi # Check if libnotify is installed if ! command -v notify-send >/dev/null 2>&1; then echo "ERROR: notify-send command not found" echo "Try: sudo apt-get install libnotify-bin" fi # Test basic notification if notify-send "Test" "This is a test notification" 2>/dev/null; then echo "SUCCESS: Basic notification works" else echo "ERROR: Failed to send test notification" fi } Run troubleshooting troubleshoot_desktop_notifications ``` Email Configuration Issues Troubleshoot email notification problems: ```bash #!/bin/bash Email troubleshooting function troubleshoot_email_notifications() { echo "Troubleshooting email notifications..." # Check if mail command exists if ! command -v mail >/dev/null 2>&1; then echo "ERROR: mail command not found" echo "Try: sudo apt-get install mailutils" return 1 fi # Check postfix status if systemctl is-active --quiet postfix; then echo "SUCCESS: Postfix is running" else echo "ERROR: Postfix is not running" echo "Try: sudo systemctl start postfix" fi # Check mail queue local queue_count=$(mailq | grep -c "^[A-F0-9]") if [[ $queue_count -gt 0 ]]; then echo "WARNING: $queue_count messages in mail queue" echo "Check with: mailq" fi # Test email sending if echo "Test message" | mail -s "Test Subject" "$USER@localhost" 2>/dev/null; then echo "SUCCESS: Test email sent" else echo "ERROR: Failed to send test email" fi } Run email troubleshooting troubleshoot_email_notifications ``` Permission Issues Handle permission-related problems: ```bash #!/bin/bash Check and fix common permission issues fix_notification_permissions() { # Check log file permissions local log_file="/var/log/script-notifications.log" if [[ ! -w "$log_file" ]]; then echo "Fixing log file permissions..." sudo touch "$log_file" sudo chmod 664 "$log_file" sudo chown "$USER":adm "$log_file" fi # Check notification queue directory permissions local queue_dir="/tmp/notification_queue" if [[ ! -w "$queue_dir" ]]; then echo "Creating notification queue directory..." mkdir -p "$queue_dir" chmod 755 "$queue_dir" fi # Check access to sound files if [[ ! -r "/usr/share/sounds" ]]; then echo "WARNING: Cannot access system sound files" fi } Run permission fixes fix_notification_permissions ``` Best Practices and Tips Performance Considerations Optimize notification performance: ```bash #!/bin/bash Efficient notification batching batch_notifications() { local notifications=() local batch_size=5 # Collect notifications while IFS= read -r line; do notifications+=("$line") done # Process in batches for ((i=0; i<${#notifications[@]}; i+=batch_size)); do local batch=("${notifications[@]:$i:$batch_size}") # Combine multiple notifications into one local combined_message="" for notification in "${batch[@]}"; do combined_message+="• $notification"$'\n' done notify-send "Batch Notification" "$combined_message" sleep 2 # Prevent overwhelming the user done } Rate limiting declare -A last_notification_time rate_limited_notify() { local key="$1" local title="$2" local message="$3" local min_interval="${4:-30}" # Minimum seconds between notifications local current_time=$(date +%s) local last_time=${last_notification_time[$key]:-0} if [[ $((current_time - last_time)) -ge $min_interval ]]; then notify-send "$title" "$message" last_notification_time[$key]=$current_time fi } ``` Security Best Practices Implement secure notification handling: ```bash #!/bin/bash Secure email notifications secure_email_notify() { local recipient="$1" local subject="$2" local message="$3" # Validate email address if [[ ! "$recipient" =~ ^[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,}$ ]]; then echo "ERROR: Invalid email address format" return 1 fi # Sanitize subject and message subject=$(echo "$subject" | tr -d '\n\r' | head -c 100) message=$(echo "$message" | head -c 1000) # Send with timeout timeout 30 mail -s "$subject" "$recipient" <<< "$message" } Secure logging secure_log() { local level="$1" local message="$2" local log_file="/var/log/secure-notifications.log" # Sanitize log message message=$(echo "$message" | sed 's/[^[:print:]]//g' | head -c 500) # Log with proper permissions { echo "[$(date '+%Y-%m-%d %H:%M:%S')] [$level] $message" } | sudo tee -a "$log_file" >/dev/null sudo chmod 640 "$log_file" } ``` Error Handling Implement robust error handling: ```bash #!/bin/bash Comprehensive notification function with error handling robust_notify() { local title="$1" local message="$2" local methods=("${@:3}") local success=false for method in "${methods[@]}"; do case "$method" in "desktop") if notify-send "$title" "$message" 2>/dev/null; then success=true break fi ;; "email") if echo "$message" | mail -s "$title" "$EMAIL_ADMIN" 2>/dev/null; then success=true break fi ;; "log") if logger -t "script-notification" "$title: $message" 2>/dev/null; then success=true break fi ;; "sound") if echo -e "\a" 2>/dev/null; then success=true break fi ;; esac done if [[ "$success" != "true" ]]; then # Fallback to stderr echo "NOTIFICATION FAILED: $title - $message" >&2 return 1 fi return 0 } Usage with fallback methods robust_notify "System Alert" "Critical error occurred" "desktop" "email" "log" "sound" ``` Configuration Management Manage notification configurations effectively: ```bash #!/bin/bash CONFIG_FILE="/etc/notification-config.conf" Default configuration create_default_config() { cat > "$CONFIG_FILE" << 'EOF' Notification Configuration ENABLE_DESKTOP_NOTIFICATIONS=true ENABLE_EMAIL_NOTIFICATIONS=true ENABLE_SOUND_NOTIFICATIONS=false Email settings EMAIL_RECIPIENTS=("admin@example.com" "user@example.com") EMAIL_SMTP_SERVER="smtp.example.com" EMAIL_PORT=587 Desktop notification settings NOTIFICATION_TIMEOUT=5000 DEFAULT_URGENCY="normal" Sound settings SOUND_THEME="freedesktop" VOLUME_LEVEL=50 Quiet hours (24-hour format) QUIET_HOURS_START="22:00" QUIET_HOURS_END="08:00" Log settings LOG_LEVEL="INFO" LOG_ROTATION_SIZE="10M" EOF } Load configuration with validation load_config() { if [[ -f "$CONFIG_FILE" ]]; then source "$CONFIG_FILE" # Validate configuration if [[ ! "${EMAIL_RECIPIENTS[@]}" ]]; then echo "WARNING: No email recipients configured" fi if [[ ! "$LOG_LEVEL" =~ ^(DEBUG|INFO|WARNING|ERROR)$ ]]; then echo "WARNING: Invalid log level, using INFO" LOG_LEVEL="INFO" fi else echo "Configuration file not found, creating default..." create_default_config source "$CONFIG_FILE" fi } Configuration validation function validate_config() { local errors=0 # Check email configuration if [[ "$ENABLE_EMAIL_NOTIFICATIONS" == "true" ]]; then if [[ -z "${EMAIL_RECIPIENTS[@]}" ]]; then echo "ERROR: Email notifications enabled but no recipients configured" ((errors++)) fi for email in "${EMAIL_RECIPIENTS[@]}"; do if [[ ! "$email" =~ ^[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,}$ ]]; then echo "ERROR: Invalid email address: $email" ((errors++)) fi done fi # Check desktop notification settings if [[ "$ENABLE_DESKTOP_NOTIFICATIONS" == "true" ]]; then if ! command -v notify-send >/dev/null 2>&1; then echo "ERROR: Desktop notifications enabled but notify-send not found" ((errors++)) fi fi # Check sound settings if [[ "$ENABLE_SOUND_NOTIFICATIONS" == "true" ]]; then if ! command -v paplay >/dev/null 2>&1 && ! command -v aplay >/dev/null 2>&1; then echo "ERROR: Sound notifications enabled but no audio player found" ((errors++)) fi fi return $errors } Initialize configuration load_config if ! validate_config; then echo "Configuration validation failed. Please check your settings." exit 1 fi ``` Monitoring and Analytics Implement notification monitoring and analytics: ```bash #!/bin/bash ANALYTICS_FILE="/var/log/notification-analytics.log" Track notification metrics track_notification() { local method="$1" local level="$2" local success="$3" local response_time="$4" local timestamp=$(date '+%Y-%m-%d %H:%M:%S') local entry="$timestamp,$method,$level,$success,$response_time" echo "$entry" >> "$ANALYTICS_FILE" } Generate notification report generate_notification_report() { local days="${1:-7}" local since_date=$(date -d "$days days ago" '+%Y-%m-%d') echo "Notification Report - Last $days days" echo "======================================" # Total notifications local total=$(awk -F, -v date="$since_date" '$1 >= date' "$ANALYTICS_FILE" | wc -l) echo "Total notifications sent: $total" # Success rate by method echo "" echo "Success rate by method:" awk -F, -v date="$since_date" ' $1 >= date { method_total[$2]++ if ($4 == "true") method_success[$2]++ } END { for (method in method_total) { success_rate = (method_success[method] / method_total[method]) * 100 printf " %s: %.1f%% (%d/%d)\n", method, success_rate, method_success[method], method_total[method] } }' "$ANALYTICS_FILE" # Average response time echo "" echo "Average response times:" awk -F, -v date="$since_date" ' $1 >= date && $5 != "" { method_times[$2] += $5 method_counts[$2]++ } END { for (method in method_times) { avg_time = method_times[method] / method_counts[method] printf " %s: %.2f seconds\n", method, avg_time } }' "$ANALYTICS_FILE" } Notification health check notification_health_check() { local threshold_failures=10 local threshold_response_time=5.0 # Check recent failures local recent_failures=$(tail -100 "$ANALYTICS_FILE" | awk -F, '$4 == "false"' | wc -l) if [[ $recent_failures -gt $threshold_failures ]]; then echo "HEALTH WARNING: $recent_failures notification failures in recent activity" return 1 fi # Check average response time local avg_response=$(tail -100 "$ANALYTICS_FILE" | awk -F, '$5 != "" {sum+=$5; count++} END {print sum/count}') if (( $(echo "$avg_response > $threshold_response_time" | bc -l) )); then echo "HEALTH WARNING: Average response time ($avg_response s) exceeds threshold ($threshold_response_time s)" return 1 fi echo "HEALTH OK: Notification system operating normally" return 0 } Usage examples track_notification "desktop" "INFO" "true" "0.5" track_notification "email" "ERROR" "false" "30.0" generate_notification_report 7 notification_health_check ``` Conclusion Implementing effective notification systems in Linux scripts is crucial for creating responsive and user-friendly automated systems. This comprehensive guide has covered various notification methods, from simple desktop notifications to complex custom solutions, each serving different use cases and environments. Key Takeaways 1. Choose the Right Method: Select notification methods based on your environment and requirements. Desktop notifications work well for interactive systems, while email notifications are essential for server environments. 2. Implement Error Handling: Always include proper error handling and fallback mechanisms to ensure critical notifications are delivered even when primary methods fail. 3. Consider User Experience: Implement rate limiting, quiet hours, and batching to prevent notification spam and respect user preferences. 4. Security Matters: Sanitize inputs, validate email addresses, and use secure logging practices to prevent security vulnerabilities. 5. Monitor and Optimize: Track notification performance and success rates to identify issues and optimize your notification systems. Best Practices Summary - Use configuration files for flexible notification management - Implement multiple notification channels for redundancy - Log all notifications for auditing and troubleshooting - Test your notification systems regularly - Consider the user experience and avoid notification fatigue - Secure your notification systems against potential exploits - Monitor notification performance and success rates Future Considerations As your scripts and systems evolve, consider implementing more advanced features such as: - Integration with modern messaging platforms (Slack, Teams, Discord) - Mobile push notifications through services like Pushover or PushBullet - Advanced analytics and machine learning for intelligent notification routing - Integration with monitoring systems like Nagios, Zabbix, or Prometheus - Custom notification dashboards and management interfaces By following the practices and techniques outlined in this guide, you'll be well-equipped to create robust, reliable, and user-friendly notification systems for your Linux scripts and automated processes. Remember to continuously evaluate and improve your notification systems based on user feedback and changing requirements. The notification landscape continues to evolve, with new tools and services constantly emerging. Stay informed about new developments and be prepared to adapt your notification strategies to leverage new technologies and best practices as they become available.