如何利用 curl 通过 SMTP 发送邮件
在自动化运维或脚本编写中,直接使用 Linux 系统自带的 curl 即可通过 SMTP 协议发送告警或通知邮件。
🛠️ 发信前的准备工作(以 Gmail 为例)
- 前往 security,确认两步验证已开启。
- 访问 App Password,创建一个应用专用密码(生成的 16 位随机字母即为
curl命令中的密码)。
📄 第一步:编写邮件内容文件 (mail.txt)
邮件本质上是一个符合 MIME 规范的文本文件(邮件头与正文之间必须保留一个空行):
From: Jiacai Liu <[email protected]>
To: Joe Smith <[email protected]>
Subject: 命令行 curl 发信测试
Date: Fri, 7 Aug 2026 19:19:00 -0700
Dear Joe,
这是一封通过 curl 直接发送的测试邮件。
💻 第二步:运行 curl 命令发送
curl smtps://smtp.gmail.com \
--user "[email protected]:您的16位应用专用密码" \
--mail-from "[email protected]" \
--mail-rcpt "[email protected]" \
--upload-file mail.txt
💡 核心概念:MIME Header vs SMTP Envelope
在电子邮件传输中,邮件内容(Header) 与 信封传输(Envelope) 是完全独立的:
| 维度 | MIME Header (邮件文本头部) | SMTP Envelope (SMTP 传输指令) |
|---|---|---|
| 生效位置 | 写入 mail.txt 文件中 (From:, To:) | 传给 curl 的命令行参数 (--mail-from, --mail-rcpt) |
| 主要作用 | 邮件客户端(Gmail / Outlook)展示给收件人看 | SMTP 服务器握手路由,决定信件实际投递给谁 |
| 格式要求 | 支持 Display Name,如 Display Name <[email protected]> | 必须为纯 Email 地址(如 [email protected]),不能包含 Display Name |
| 多收件人 | 逗号分隔,如 To: [email protected], [email protected] | 必须重复传参,如 --mail-rcpt "[email protected]" --mail-rcpt "[email protected]" |
⚠️ 踩坑提示 1:如果直接把包含 Display Name 的字符串
Name <[email protected]>传给curl --mail-rcpt,curl会在最外层包裹角括号变成RCPT TO:<Name <[email protected]>,导致 SMTP 服务器抛出555 Syntax error。在脚本中给curl传参前必须提取出纯邮箱地址。
⚠️ 踩坑提示 2:非 ASCII 字符(中文)导致对方显示
no subject(RFC 2047) SMTP 规范(RFC 5322)要求邮件头(Subject:,From:中的 Display Name 等)必须仅包含 7-bit ASCII 字符。如果在Subject中直接写入中文而未经编码,在经过 Gmail / Google Groups / Outlook 等邮件服务解析 Header 时会失败,接收方将显示为(no subject)/ 无主题。解决方法:按照 RFC 2047 规范,将包含中文的 Header 包装为 UTF-8 Base64 编码格式:
=?UTF-8?B?<base64>?=。可以在 Bash 脚本中自动处理:
# Encode header using RFC 2047 UTF-8 Base64 format SUBJECT_ENCODED="=?UTF-8?B?$(printf "%s" "$SUBJECT" | base64 | tr -d '\r\n')?="写入
mail.txt时输出:Subject: =?UTF-8?B?44CQWmlnIMpelp报44CR6aG555uu5YiG5Lqr...=?=
💡 进阶小贴士
- GitHub Actions 集成:如果需要在 GitHub Workflows 中自动化发送邮件,推荐使用基于本文踩坑经验封装的 Composite Action:jiacai2050/sendmail-action。该 Action 内置了纯邮箱地址自动提取、RFC 2047 中文 Header 自动编码及 Multipart HTML 等特性,开箱即用。
- 密送 (BCC):只需在
curl中并列增加--mail-rcpt,但不要在mail.txt的To:或Cc:头部写入该邮箱。 - 防止误判垃圾邮件:建议显式在
mail.txt中包含格式规范的Date:字段。