linux系统中mail命令需依赖本地mta(如postfix/sendmail)才能发外网邮件;先用which mail确认命令存在,再用mailq或postqueue -p检查mta状态,debian默认无mta,centos/rhel 7+默认装postfix;发信失败常因dns、rdns、防火墙或垃圾邮件策略导致。

Linux Shell 中发邮件,别急着装 mailx 或配 SMTP —— 大多数系统自带 mail 命令就能用,但默认不发外网邮件,得先确认本地 MTA 是否在跑。
怎么判断系统有没有可用的邮件发送能力
直接运行 which mail 或 which sendmail。如果返回路径(比如 /usr/bin/mail),说明命令存在;但存在 ≠ 能发外网邮件。接着检查本地邮件队列:mailq(对应 sendmail)或 postqueue -p(对应 postfix)。若报 “command not found”,大概率没装 MTA,mail 命令只是个空壳。
- Debian/Ubuntu 默认不装 MTA,
mail是mailutils提供的,但背后没服务,只能写入本地 mbox - CentOS/RHEL 7+ 默认装了
postfix,启动后mail才真能发出去 - 用
systemctl is-active postfix或systemctl is-active sendmail看状态
mail 命令发邮件的基本写法和常见失败点
最简用法:echo "body" | mail -s "subject" user@example.com。但它依赖本地 MTA 正确配置:收件人域名要能被解析,发信主机要有反向 DNS(很多外网邮箱拒收无 rDNS 的邮件),且不能被当成垃圾邮件。
- 加
-r指定发件人(如mail -r "alert@myhost.local" -s "test"),否则可能被当匿名信拦截 - 附件要用
uuencode或改用mutt:echo "log" | mutt -s "log" -a /var/log/syslog -- admin@example.com - 如果收件人收不到,先查
/var/log/mail.log(Debian)或/var/log/maillog(RHEL),看有没有 “relaying denied” 或 “connection refused”
不想配 MTA?用 curl 调第三方 SMTP API 更稳
绕过本地邮件服务,直接走 HTTPS 发送,适合脚本告警。例如用 Mailgun、SendGrid 或腾讯云 SES,只需 API Key 和模板 ID。
- Mailgun 示例:
curl -s --url 'smtps://api:key-xxx@smtp.mailgun.org:465' --ssl-reqd --mail-from 'alert@mg.mydomain.com' --mail-rcpt 'admin@example.com' --upload-file /tmp/email.txt,其中/tmp/email.txt是符合 SMTP 协议的原始邮件内容(含To:、From:、空行分隔头与正文) - 更轻量做法:用 Python 的
smtplib写三行脚本,比 shell + curl 更易处理认证和编码 - 注意:不要把 API Key 硬编码进脚本,用
export MAILGUN_API_KEY="xxx"+${MAILGUN_API_KEY}引用
真正卡住人的往往不是“怎么写命令”,而是“为什么明明没报错却收不到邮件”——本地 MTA 配置、DNS 解析、反垃圾策略、防火墙屏蔽 25/465 端口,这些环节任何一个断掉,mail 就静默失败。建议首次调试时,先用 logger 记日志,再盯 /var/log/mail* 的每一行输出。










