RedHat Radius服务器Shell脚本邮件格式优化及重复发送问题求助
Fixing Radius Invalid User Alert Script: Preserve Duplicate Detection & Proper Formatting
Let's break down your issues and fix the script while keeping all original functionality plus clean, readable email formatting:
The Root Causes of Your Problems
mailx -Estopped working: Your formatted output always included separator lines and blank spaces, even when there were no new invalid user entries. This meant the email was never truly empty, so-E(which skips sending empty emails) had nothing to block.- Lost duplicate detection: You removed the core
commlogic that compared new logs against previously sent entries, so the script kept trying to send content even when there was nothing new.
Fixed Script with Explanations
#!/bin/bash # Define configurable constants for easy maintenance LOG_FILE="radius.log" TRIGGER_PHRASE="Invalid user" SENT_LOGS_TRACKER="myFile" ALERT_EMAIL="myuser@email.com" EMAIL_SUBJECT="Radius-Invalid-User Alert" while : do # Grab all current invalid user entries from the log current_alerts=$(grep "$TRIGGER_PHRASE" "$LOG_FILE") # Determine new, unsent entries if [ ! -e "$SENT_LOGS_TRACKER" ]; then # First run: no tracking file exists, use all current alerts new_alerts="$current_alerts" else # Compare current alerts against already sent ones, keep only new entries new_alerts=$(comm -23 <(echo "$current_alerts") "$SENT_LOGS_TRACKER") fi # Only process and send email if there are new alerts if [ -n "$new_alerts" ]; then # Update the tracking file with all current alerts to avoid duplicates next cycle echo "$current_alerts" > "$SENT_LOGS_TRACKER" # Generate clean, formatted email content from new alerts formatted_email=$(echo "$new_alerts" | awk ' BEGIN { print "|-------------------------------------------------------------|" print " " } { # Parse fields from your log format (adjust indices if your log structure changes!) switch_name = $19 port_number = $21 mac_address = $11 gsub(/[()]/, "", mac_address) # Clean up parentheses around MAC # Build formatted block for each alert print " Switch: " switch_name print " " print "|-------------------------------------------------------------|" print " " print " Port-Nr: " port_number print " " print "|-------------------------------------------------------------|" print " " print " MAC-Address: " mac_address print " " print "|-------------------------------------------------------------|" print " " }') # Send the formatted email - -E will work because we only run this when content exists echo "$formatted_email" | mailx -E -s "$EMAIL_SUBJECT" "$ALERT_EMAIL" fi # Adjust sleep time to reduce system load (1 second is very frequent; 60 seconds is more reasonable) sleep 60 done
Key Improvements
- Restored duplicate detection: The
comm -23logic is retained to ensure only new invalid user attempts trigger an email. - Fixed
mailx -Ebehavior: We only generate and send email when there are actual new alerts, so the content is never empty when we reach themailxcommand. - Better formatting handling: Uses
awkto loop through every new alert entry (not just the last one in the file) and clean up fields like the MAC address. - Maintainable structure: Constants at the top make it easy to update log paths, email addresses, or sleep intervals without digging into the script logic.
Important Notes
- Double-check the field indices (
$19,$21,$11) in theawkblock. If your Radius log format changes, you'll need to adjust these to match the actual position of switch name, port, and MAC address in your logs. - Consider increasing the
sleepvalue from 1 second to 60 (or longer) to reduce unnecessary system resource usage.
内容的提问来源于stack exchange,提问作者averagejoe
相关产品推荐
相关产品推荐

