米扑博客前几篇介绍了CentOS 安装 sendmail,以及使用 mailx(mail)发送邮件,详见:

Centos7 使用 sendmail 发送邮件

Python学习入门(5)——发送邮件

POP3、SMTP、IMAP 的作用和联系

 

本文将介绍 sendmail 命令,查看帮助 man sendmail ,但不支持 sendmail --help

 

sendmail 命令

sendmail 命令是一款著名的电子邮件传送代理程序,也就是平常说的电子邮件服务器,它基于标准的简单邮件传输协议(SMTP)

语法:sendmail (选项)

选项:

-bd:以守护进程方式运行指令;
-bD:以前台运行方式运行;
-bi:初始化别名数据库;
-bm:以常规发送电子邮件;
-bp:显示邮件的发送队列;
-C:指定配置文件;
-D:将调试的输出信息保存到日志文件,而不显示在标准输出设备上;
-F:指定邮件发送者全名;
-n:禁止使用邮件别名功能;
-f:指定发件人的名字;
-q:设置处理邮件队列中邮件的时间间隔。

 

 

sendmail 命令的使用参数

sendmail 命令用途,为本地或网络交付传送邮件。

 

语法

sendmail [  -ba | -bd | -bD | -bh | -bH | -bi | -bm | -bp | -bs | -bv | -bt [  -CFile ] [  -dValue ] ] [  -BType ] [  -FFullName ] [  -fName ] [  -hNumber ] [  -i ] [ -Mx Value] [  -n ] [  -N Dsn ] [  -OOption=Value ] [  -o Option [ Value ] ] [  -pProtocol ] [  -q [ Time] ] [  -qISubstr  ] [  -qRSubstr ] [  -qSSubstr ] [  -R Return ] [  -r addr ] [  -t ] [  -U ] [  -V Envid ] ] [  -v ] [  -X LogFile ] Address

注: "bold">-bd、 -bi、 "bold">-bp、-bt、 "bold">-q [  "italic">Time ] 标志 和  "italic">Address 参数是可选的。

在 sendmail V8.7(AIX 4.2 及以后的版本)中,名称解析顺序是DNS、NIS,然后是本地。如果您想覆盖它,则指定  "bold">/etc/netsvc.conf 文件或 NSORDER 环境变量。

sendmail 命令接收格式化文本消息并把它们发送到一个或更多的用户。在网络上使用时,sendmail命令转换消息的头信息格式以匹配目的系统的要求。程序使用地址的语法和内容来确定目的系统的网络。

sendmail 命令可以把消息传送到:

本地系统用户,使用 TCP/IP 协议连接到本地系统的用户。

使用基本网络实用程序(BNU)命令协议连接到本地系统的用户。

sendmail命令并不是用来作为一个用户界面例程;其它的命令提供用户友好的界面。使用sendmail 命令只是用来传送预格式化的消息。

sendmail 命令从标准输入中读取消息文本。当读到消息字符的结尾(文件结束符(Ctrl-D)控制序列或者一行中的单一句点)时,sendmail 命令将把消息副本发送到所列的全部地址。

 

使用配置文件

sendmail 命令使用配置文件(缺省情况下为 /etc/mail/sendmail.cf 文件)设置可操作的参数并且确定命令如何分析地址。此文件是文本文件,您可以用其它的文本编辑器对它进行编辑。修改sendmail.cf 以后, 请刷新 sendmail 守护进程。

sendmail命令的当前进程标识存储在 /etc/mail/sendmail.pid 文件中。如下发出 kill -15 命令,使 sendmail 命令重新读取新编辑的 sendmail.cf:

kill -15 `head -1 /etc/mail/sendmail.pid`

如果 srcmstr 命令正在运行,则您可以发出如下的 refresh 命令来重新构建配置数据库、别名数据库和 NLS 数据库。

refresh-s sendmail

sendmail 命令重新读取这些数据库并且继续操作新数据。

 

定义别名

当 sendmail 命令处理本地邮件时,sendmail 命令允许您定义使用的别名。别名是备用名称,您可用它来代替详细的网络地址。您也可以使用别名构建分发列表。

在 /etc/mail/aliases 文件中定义别名。此文件是可以编辑的文本文件。sendmail 命令使用此文件的数据库版本。必须在 /etc/mail/aliases 文件的任和更改生效之前,运行 sendmail -bi命令或 newaliases 命令来构建新的别名数据库。

现在,在 AIX 5.1 for Sendmail 8.11.0 上可使用 Berkeley DB。Sendmail 将继续读取 DBM 格式的别名直到别名数据库获得重建。一旦重建,sendmail 将读取 Berkeley DB 格式的别名并把它们存储在 /etc/mail/aliases.db 文件中。

"bold">注:当在  "bold">/etc/mail/aliases 文件中定义别名时,对嵌套的别名只能用小写字符。别名右手边的大写字符在存储到别名数据库之前转换为小写字母。在以下示例中,由于存储第二行时TEST 转换成 test,因此发送到 testalias 的邮件失败。
TEST: user@machine
testalias: TEST

每个系统必须有一个被指定为 postmaster 别名的用户或用户别名。postmaster 别名的缺省值是一个 root 文件。在 /etc/mail/aliases 文件中您可以将此别名指定给不同的用户。postmaster 别名允许您系统以外的其它用户把邮件发送到一个已知的标识并获取有关邮寄到您系统上的用户的信息。您系统上的用户也可以把问题通知发送到 postmaster 标识。

标志

-BType 将正文主体类型设置为 type。当前合法值是 7BI 或 8BITMIME。 注: "bold">-b 标志是相互排斥的。
-ba 以 ARPANET 方式启动 sendmail 命令。命令的所有输入行必须以回车符和换行符(CR-LF)结束。sendmail 命令生成以 CR-LF 结尾的消息,并查看 From: 与Sender: 字段来查找发件人的名字。
-bd 启动 sendmail 命令使其像“简单邮件传输协议”(SMTP)邮件路由器一样作为守护进程在后台运行。
-bD 启动 sendmail 命令使其像“简单邮件传输协议”(SMTP)邮件路由器一样作为守护进程在前台运行。
-bh 打印持久主机状态数据库。
-bH 清除持久主机状态数据库。
-bi 根据 /etc/mail/aliases 文件中定义的信息构建别名数据库。用此标志运行 sendmail 命令和运行 /usr/sbin/newaliases 命令一样。
-bm 以普通方式传送邮件。(这是缺省值。)
-bp 打印邮件队列列表。用此标志运行 sendmail 命令和运行 /usr/sbin/mailq 命令一样。
-bs 使用如 RFC821 中描述的简单邮件传输协议(SMTP)收集来自标准输入的邮件。此标志也包含所有与 SMTP 兼容的 -ba 标志的操作。
-bt 以地址测试方式启动 sendmail 命令。此方式允许您输入交互式地址并在 sendmail 命令显示其分析地址所采取的步骤时进行监视。在测试方式提示符下,输入一个规则集或用逗号分割的多个规则集并输入地址。使用此方式来调试新配置文件中的地址分析规则。
-bv 用验证此命令 Address 参数字段所提供的用户标识符的请求来启动 sendmail 命令。sendmail 命令返回一条消息作为响应,告诉哪些标识可由邮件程序解析。它并不尝试收集或传送消息。使用此模式验证用户标识、别名或邮递列表的格式。
-CFile 用 File 变量指定的备用配置文件启动 sendmail 命令。在安装用作运行的配置文件的新配置文件之前,和 -bt 一起使用此标识来测试该文件。
-dValue 将调试值设置为 Value 变量所指定的值。唯一的有效值是 21.n,其中 n 是任意非零整数。它产生关于地址分析的信息并且通常和 -bt 标志一起使用。n 的更高值生成更多的详细信息。
-FFullName 将发件人的全名设置为 FullName 变量所提供的字符串。
-fName 设置发件人的名字(邮件的信包发件人)。如果在初始提交过程中 From: 头丢失,则在该头中仍可以使用这个地址。信包发件人的地址用作传送状态通知的接收方,也可以出现在 Return-path: 头中。只有可信的用户(一般是 root 用户、守护进程以及 uucp)或者如果您试图成为的那个人就是您本人的话才能使用此标志。否则,X-Authentication-Warning 头将添加到消息中。
-hNumber 将跳计数设置为 Number 变量所指定的值。跳计数是 SMTP 路由器(不仅仅是 sendmail 命令的本地副本)所处理消息的次数。每次消息处理后,邮件路由器就增加跳计数。当它到达限制时,就会返回一条错误消息以在防止邮件系统中的无限循环。
-i 忽略进入消息的行中单独的点。如果您正在从文件读取数据的话,必须设置它。
-L 将系统日志消息中使用的标识设置为供给的标记。
-Mx Value 将宏 x 设置为指定的 Value。
-N Dsn 将传送状态通知条件设置为 DSN。传送状态通知条件可以是:never 表示没有通知或者用逗号分隔的值的列表,failure 表示发送失败的通知,delay 表示发送延迟的通知,以及 success 表示消息成功发送的通知。
-n 阻止 sendmail 命令解释别名。
-O Option=Value 将 Option 设置为指定的 Value。使用长格式选项名称。此标志仅应用于 AIX 4.2 或者以后的版本。
-oOption [ Value ] 设置 Option 变量。如果选项是一个有值的选项,您也必须为 Value 变量指定一个值。 注:对于有效值,请查看 "italic">《AIX 5L V5.2 系统管理指南:通信与网络》中的『sendmail.cf
文件中 sendmail 的命令选项』。
-pProtocol 设置发送协议。建议您设置此项。您可以以 Protocol:Host 格式设置发送协议和发送主机来设置 Protocol。例如,-pUUCP:uunet 将发送协议设置为 UUCP 并将发送主机设置为 uunet。一些现有的程序使用 -oM 标志设置 r 和 s 宏,它和使用 -p 标志是等效的。此标志仅适用于 4.2 版本或以后的版本。
-qISubstr 将进程作业限制为那些包含作为队列标识的 Substr。
-qRSubstr 将进程作业限制为那些包含作为收件人之一的子串的 Substr。
-qSSubstr 将进程作业限制为那些包含作为发件人的子串的 Substr。
-q [ Time ] 在 Time 变量指定的间隔中处理队列中保存的消息。如果没有指定 Time 变量,则该标志立即处理队列。
-R Return 设置如果消息弹回要返回的消息的量。Return 参数可以为 full 以表示返回整个信息或者为 hdrs 以表示仅能返回头部分。
-r addr -f 的废弃格式。
-t 把消息发送到消息头的 To:Cc: 以及 Bcc: 字段中指定的收件人,也可以发送到命令行中指定的任何用户。
-U 设置初始(用户)提交。当被诸如 Mail 或 exmh 用户代理调用时,应当设置此项,但是当被诸如 rmail 网络传送代理调用时切勿设置此项。
-V Envid 设置原始信包标识。它可以通过 SMTP 传播到支持 DSN 的服务器上,并且以 DSN 兼容的错误消息返回。
-v 以详细的方式启动 sendmail 命令。sendmail 命令显示有关传送状态和别名扩展的消息。
-X LogFile 为了调试邮件程序问题,记录 LogFile 中 sendmail 的所有进出流量。由于它迅速地产生大量的数据,因此尽可能不使用此标志。此标志仅适用于 4.2 版本或以后的版本。

您也可以设置或除去 sendmail 配置处理选项。负责邮件系统的人使用这些选项。为设置这些选项,在命令行中使用 -o 标志或者使用配置文件(/etc/mail/sendmail.cf)中的 O 控制行。

 

安全性

审计事件:

事件 信息
SENDMAIL_Config 配置事件
SENDMAIL_ToFile 创建文件事件

 

退出状态

sendmail 命令返回退出状态值。这些返回值在 /usr/include/sysexits.h 文件中定义。下列表总结了这些返回值的含义:

EX_CANTCREAT sendmail 命令不能创建用户指定的文件。
EX_CONFIG 在配置文件的格式中发现到错误。
EX_DATAERR 某种方式下输入的数据不正确。
EX_IOERR 在 I/O 过程中产生错误。
EX_NOHOST sendmail 命令无法识别指定的主机名。
EX_NOINPUT 输入文件(非系统文件)不存在或者不可读。
EX_NOPERM 用户没有执行所请求的操作的许可权。
EX_NOUSER sendmail 命令无法识别指定的用户标识。
EX_OK sendmail 命令成功完成。
EX_OSERR 出现一个临时操作系统错误。这种错误的一个示例是创建一个新的进程失败。
EX_OSFILE 出现系统文件错误。例如,系统文件(例如 /etc/passwd)不存在、无法打开或者有另一种类型的错误阻止使用它。
EX_PROTOCOL 在协议交换过程中,远程系统返回一些不正确的东西。
EX_SOFTWARE 出现一个内部软件错误(包含坏的参数)。
EX_TEMPFAIL sendmail 命令无法创建与远程系统的连接。稍后重新尝试请求。
EX_UNAVAILABLE sendmail 命令所需的服务或资源不可用。
EX_USAGE 命令语法不正确。

 

文件

/usr/sbin/sendmail 包含 sendmail 命令。
/usr/sbin/mailq 包含邮件队列。
/usr/sbin/newaliases 包含别名数据库。
/usr/sbin/mailstats 包含在 /usr/lib/sendmail.st 文件中查找到的统计信息。
/etc/mail/aliases 包含 sendmail 命令别名的文字版。
/etc/mail/aliases.db 包含 Berkeley DB 格式化的别名数据库。
/etc/mail/aliases.dir 包含 DBM 格式化的别名数据库。
/etc/mail/aliases.pag 包含 DBM 格式化的别名数据库。
/etc/mail/sendmail.cf 包含 sendmail 配置文件的文字版。
/etc/sendmail.st 包含邮件路由的统计信息。
/usr/lib/smdemon.cleanu 维护在 /var/spool/mqueue 目录下查找到的日志文件的老化副本。
/var/spool/mqueue 包含与邮件队列中的消息相关的临时文件和日志文件。
/usr/bin/uux 包含用于传送“基本联网实用程序”(BNU)的邮件程序命令。
/usr/bin/bellmail 包含用于传送本地邮件的邮件程序命令。

 

 

sendmail 发送邮件示例

调用本机linux自身sendmail服务发送邮件,不需要启动sendmail后台进程,不需要发送者登录,邮件发送者可以是任意名字,没有限制。

特别注意:sendmail 命令发送邮件,默认用25端口号,由于阿里云、腾讯云等封禁了25端口号,因此本示例需在开通25端口机器上测试

vim send_mail.py

#!/usr/bin/env python
# -*- coding:utf-8 -*-
#
# author: mimvp.com
# 2015.10.05


from email.mime.text import MIMEText
from subprocess import Popen, PIPE
import commands

import sys 
reload(sys)
sys.setdefaultencoding('utf-8')

def send_mail(sender, recevier, subject, html_content):
        msg = MIMEText(html_content, 'html', 'utf-8')
        msg["From"] = sender
        msg["To"] = recevier
        msg["Subject"] = subject
        p = Popen(["/usr/sbin/sendmail", "-t"], stdin=PIPE)
        p.communicate(msg.as_string())


sender = 'robot@mimvp.com'
recevier = 'yanggang@mimvp.com'
subject = 'sendmail-subject'
html_content = 'hello mimvp.com'
send_mail(sender, recevier, subject, html_content)

执行命令:

python send_mail.py

收件结果:

 

思考:

由于阿里云、腾讯云等封禁了25端口号,那么如何采用 SSL 465端口号来发送邮件呢?

感兴趣的同学,欢迎留言交流哈~

 

 

参考推荐

Centos7 使用 sendmail 发送邮件

CentOS7 使用 postfix 发送邮件

Linux shell 发送 email 邮件

Linux shell 发送 email 附件

CentOS 6使用mutt+msmtp发送邮件

POP3、SMTP、IMAP 的作用和联系

Linux用Sendmail架设Mail服务器

CentOS SendMail总结

Python学习入门(5)——发送邮件

Python 七种邮件内容发送方法

Python smtp 群发邮件