Linux Shell中封装send_mail函数可实现邮件发送的标准化:基础版支持参数校验与错误提示,增强版增加抄送、发件人伪装及中文兼容,生产版集成日志、重试与配置分离,前提是系统已正确配置MTA并验证mail命令可用。

在 Linux Shell 脚本中封装发送邮件的通用函数,核心目标是:**避免重复写 mail 命令、统一收件人/主题/内容处理、支持错误判断、便于复用和维护**。不需要依赖 Python 或外部语言,纯 Bash 即可实现简洁可靠的封装。
基础封装:一个可直接调用的 send_mail 函数
把最常用的 mail -s 场景抽象成函数,接受三个参数:收件人、主题、正文内容:
send_mail() {
local to="$1"
local subject="$2"
local body="$3"
<pre class="brush:php;toolbar:false;"># 检查必要参数
if [ -z "$to" ] || [ -z "$subject" ]; then
echo "错误:缺少收件人或主题" >&2
return 1
fi
# 发送邮件(使用管道传入正文)
echo "$body" | mail -s "$subject" "$to"
# 检查是否发送成功(mail 命令退出码为 0 表示已提交给 MTA)
if [ $? -eq 0 ]; then
echo "邮件已提交至本地邮件队列:$to"
else
echo "警告:邮件提交失败,请检查 mail 配置及 MTA 状态" >&2
fi}
调用方式示例:
send_mail "admin@example.com" "磁盘告警" "根分区使用率已达 92%!"
增强封装:支持抄送、发件人伪装与中文兼容
很多系统默认 mail 不带发件人或中文乱码,需配合 /etc/mail.rc 或环境配置。函数内可做适配:
- 通过
-r参数指定发件人(需 mail 支持且 MTA 允许) - 用
echo -e或printf确保换行符正确,避免中文被截断 - 增加
-c抄送选项,用可选参数方式传递
send_mail() {
local to="$1" subject="$2" body="$3" cc="${4:-}" from="${5:-}"
<pre class="brush:php;toolbar:false;">[ -z "$to" ] && { echo "错误:收件人不能为空" >&2; return 1; }
local cmd="mail -s '$subject'"
[ -n "$cc" ] && cmd="$cmd -c '$cc'"
[ -n "$from" ] && cmd="$cmd -r '$from'"
# 使用 printf 避免 echo 对特殊字符的误处理
if printf '%s' "$body" | eval "$cmd" "$to"; then
return 0
else
echo "邮件发送失败(可能未配置 MTA 或网络问题)" >&2
return 1
fi}
调用示例:
send_mail "alert@team.org" "服务宕机" "nginx 进程未响应" "ops@team.org" "monitor@server.local"
生产级封装:带日志、重试与配置分离
真正用于监控脚本时,建议将配置(如默认收件人、发件人、超时)抽离到变量或配置文件,函数只负责逻辑:
- 定义全局变量(如
DEFAULT_ALERT_EMAIL)或读取~/.mailconf - 添加简单重试(最多 2 次),应对临时 MTA 队列阻塞
- 记录发送时间与结果到日志文件
- 返回值严格区分:0=成功,1=参数错,2=发送失败
# 示例:轻量重试 + 日志
send_mail() {
local to="${1:-${DEFAULT_ALERT_EMAIL}}"
local subject="${2:-'无主题'}"
local body="${3:-'无内容'}"
local log_file="/var/log/alert_mail.log"
<pre class="brush:php;toolbar:false;">for i in 1 2; do
if printf '%s' "$body" | mail -s "$subject" "$to" >/dev/null 2>&1; then
logger -t "alert-mail" "sent to $to: $subject"
echo "$(date): SUCCESS $to '$subject'" >> "$log_file"
return 0
fi
sleep 1
done
logger -t "alert-mail" "FAILED after 2 tries: $to"
echo "$(date): FAILED $to '$subject'" >> "$log_file"
return 2}
关键前提:确保底层可用
函数再好,也依赖系统邮件能力。务必提前验证:
- 运行
which mail和mail -V确认命令存在 - 执行
echo test | mail -s test $(whoami)测试本地投递 - 若要发到公网邮箱(如 QQ、163),必须已配置好 MTA(Postfix/SSMTP)并能外发
- 中文支持需终端编码为 UTF-8,且 MTA 配置中声明
charset=utf-8(如 mail.rc 中加set sendcharsets=utf-8)


















