Linux中封装通用邮件告警函数send_alert,支持多收件人、分级标记、模板化主题与正文,兼容mail/sendmail/API三种发信方式,参数清晰、职责单一、配置外置。

在 Linux 系统中封装一个通用的邮件告警通知函数,核心是让脚本具备可复用、易配置、能区分级别、支持多收件人和简单模板的能力。不依赖复杂框架,用 Shell 就能实现,关键是把“变”的部分(收件人、主题、内容、严重程度)抽离出来,把“不变”的部分(发信逻辑、基础校验、日志记录)固化。
基础前提:确保系统能发邮件
函数本身不处理 MTA 配置,但必须依赖可用的命令行发信工具。常用有三种方式,任选其一并验证通:
-
mail 命令:需已配置好
/etc/mail.rc或使用外部 SMTP(如 msmtp),运行echo "test" | mail -s "test" your@em.ail能成功收到 -
sendmail 命令:常见于 CentOS/RHEL,直接调用
/usr/sbin/sendmail,无需额外配置本地 relay - curl + 邮件 API(如 SendGrid、企业微信邮箱网关):适合无法装 MTA 的容器或受限环境,需提前准备好 API key 和 endpoint
函数设计:参数清晰、职责单一
定义一个名为 send_alert 的函数,只接收必要参数,不做业务逻辑判断,由调用方决定何时触发:
-
必选参数顺序:
send_alert "to@example.com,admin@site.org" "磁盘超限告警" "根分区使用率已达94%" "critical" - to:支持逗号分隔的多个邮箱,自动去空格;不校验格式,交由 mail 程序处理
-
subject:主题字符串,自动添加前缀如
[ALERT][HOSTNAME]提高可识别性 - body:正文内容,支持换行(用 $'...' 或 here-doc 传入)
-
level:可选值
info/warn/critical,仅用于着色日志和主题标记(如 [CRITICAL])
函数实现示例(兼容 bash/sh)
以下为轻量、无依赖、带基础健壮性的实现:
<pre class="brush:php;toolbar:false;">send_alert() {
local to="$1" subject="$2" body="$3" level="${4:-info}"
local hostname=$(hostname -s 2>/dev/null || echo "unknown")
local prefix="[${level^^}][${hostname}]"
local full_subject="${prefix} ${subject}"
<h1>忽略空收件人</h1><p>[[ -z "$to" ]] && return 1</p><h1>日志记录(可重定向到文件)</h1><p>echo "$(date '+%Y-%m-%d %H:%M:%S') [ALERT] ${full_subject}" >&2</p><h1>使用 mail 命令发送(推荐:兼容性好)</h1><p>if command -v mail >/dev/null 2>&1; then
echo "$body" | mail -s "$full_subject" -r "alert@${hostname}" $(echo "$to" | tr ',' ' ')
return $?
fi</p><h1>回退 sendmail(无 mail 时)</h1><p>if command -v sendmail >/dev/null 2>&1; then
{
echo "To: $to"
echo "Subject: $full_subject"
echo "From: alert@${hostname}"
echo "Content-Type: text/plain; charset=utf-8"
echo ""
echo "$body"
} | sendmail -t
return $?
fi</p><p>echo "ERROR: no mail or sendmail command found" >&2
return 127
}</p>增强建议:提升实用性与可维护性
生产环境中可按需叠加以下改进,不破坏原有接口:
-
配置外置化:把默认发件人、SMTP 设置、告警抑制开关等写进
/etc/alert.conf或环境变量,函数内 source 加载 - 速率限制:用文件锁或时间戳记录最近一次发送时间,避免同一错误高频刷屏(如 5 分钟内同主题只发 1 次)
-
支持 HTML 或附件:当检测到 body 含 或传入第五参数
-html,则设置 Content-Type 为 text/html;附件需改用 mutt 或 curl 实现 -
对接企业通道:增加
-channel wecom参数,内部调用企业微信机器人 API 替代邮件,适合无公网邮箱的内网环境











