Linux管道输出条件执行:仅在mailq有结果时触发邮件发送


阅读 8 次

问题场景分析

在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