问题场景分析
在Linux系统运维中,我们经常需要监控邮件队列状态。典型的场景是:当邮件队列中出现被拒绝(rejected)或拒绝(refused)的邮件时,需要自动发送告警邮件给管理员。但直接使用管道连接会导致无论是否有异常都会发送邮件,这显然不够理想。
传统方案的缺陷
mailq | egrep 'rejected|refused' -A 5 -B 5 | mail -s '邮件队列异常' admin@example.com
这个命令存在两个问题:
- 无论grep是否有匹配结果都会发送邮件
- 空邮件会干扰管理员判断
条件执行解决方案
通过if判断管道输出是否为空,这是最可靠的解决方案:
output=$(mailq | egrep 'rejected|refused' -A 5 -B 5)
if [[ -n "$output" ]]; then
echo "$output" | mail -s '邮件队列异常告警' admin@example.com
fi
单行命令优化
如果确实需要单行命令,可以使用以下变体:
mailq | egrep 'rejected|refused' -A 5 -B 5 | { read -r output && echo "$output" | mail -s '告警' admin@example.com; }
生产环境增强版
实际运维中建议使用更健壮的脚本:
#!/bin/bash
LOG_FILE="/var/log/mailq_monitor.log"
THRESHOLD=5
# 检查邮件队列
queue_output=$(mailq | egrep 'rejected|refused' -A 2 -B 2)
count=$(echo "$queue_output" | wc -l)
if [[ $count -gt $THRESHOLD ]]; then
echo "[$(date)] 检测到邮件队列异常,数量:$count" >> "$LOG_FILE"
echo "$queue_output" | mail -s "紧急:邮件队列异常($count)" admin@example.com
elif [[ -n "$queue_output" ]]; then
echo "[$(date)] 检测到少量邮件队列异常" >> "$LOG_FILE"
fi
其他实用技巧
1. 使用Postfix专用检查命令:
postqueue -p | grep -E 'rejected|refused'
2. 结合logwatch工具监控:
/usr/sbin/logwatch --output mail --format html --mailto admin@example.com