提问人:Nate 提问时间:9/16/2008 最后编辑:Nate 更新时间:11/2/2020 访问量:95867
从 python 通过 sendmail 发送邮件
Sending mail via sendmail from python
问:
如果我想不通过SMTP发送邮件,而是通过sendmail发送邮件,是否有python库可以封装此过程?
更好的是,有没有一个好的库可以抽象整个“sendmail -vsus- smtp”选择?
我将在一堆 unix 主机上运行这个脚本,其中只有一些在监听 localhost:25;其中一些是嵌入式系统的一部分,无法设置为接受 SMTP。
作为良好实践的一部分,我真的很想让库本身处理标头注入漏洞——所以只是转储一个字符串比我想要的更接近金属。popen('/usr/bin/sendmail', 'w')
如果答案是“去写一个库”,那就这样吧;-)
答:
通过 os.popen 从 Python 中使用 sendmail 命令是很常见的
就我个人而言,对于不是我自己编写的脚本,我认为只使用 SMTP 协议会更好,因为它不需要安装 sendmail 克隆即可在 Windows 上运行。
https://docs.python.org/library/smtplib.html
评论
最简单的答案是 smtplib,您可以在此处找到有关它的文档。
您需要做的就是将本地 sendmail 配置为接受来自 localhost 的连接,默认情况下它可能已经这样做了。当然,您仍在使用 SMTP 进行传输,但它是本地 sendmail,这与使用命令行工具基本相同。
评论
这是一个简单的 python 函数,它使用 unix sendmail 来传递邮件。
def sendMail():
sendmail_location = "/usr/sbin/sendmail" # sendmail location
p = os.popen("%s -t" % sendmail_location, "w")
p.write("From: %s\n" % "[email protected]")
p.write("To: %s\n" % "[email protected]")
p.write("Subject: thesubject\n")
p.write("\n") # blank line separating headers from body
p.write("body of the mail")
status = p.close()
if status != 0:
print "Sendmail exit status", status
评论
popen
标头注入不是您如何发送邮件的一个因素,而是您如何构建邮件的一个因素。检查电子邮件包,用它构建邮件,序列化它,然后使用子进程模块将其发送到:/usr/sbin/sendmail
import sys
from email.mime.text import MIMEText
from subprocess import Popen, PIPE
msg = MIMEText("Here is the body of my message")
msg["From"] = "[email protected]"
msg["To"] = "[email protected]"
msg["Subject"] = "This is the subject."
p = Popen(["/usr/sbin/sendmail", "-t", "-oi"], stdin=PIPE)
# Both Python 2.X and 3.X
p.communicate(msg.as_bytes() if sys.version_info >= (3,0) else msg.as_string())
# Python 2.X
p.communicate(msg.as_string())
# Python 3.X
p.communicate(msg.as_bytes())
评论
-oi
.
.as_bytes()
as_string()
-oi
sendmail
-oi (default) Do not take dots on a line by themselves as a message terminator.
这个问题由来已久,但值得注意的是,有一个称为 Marrow Mailer(以前称为 TurboMail)的消息构建和电子邮件传递系统,该系统在提出此消息之前就已经可用。
它现在被移植以支持 Python 3,并作为 Marrow 套件的一部分进行更新。
评论
我只是在四处搜索同样的东西,并在 Python 网站上找到了一个很好的例子:http://docs.python.org/2/library/email-examples.html
从提到的网站:
# Import smtplib for the actual sending function
import smtplib
# Import the email modules we'll need
from email.mime.text import MIMEText
# Open a plain text file for reading. For this example, assume that
# the text file contains only ASCII characters.
fp = open(textfile, 'rb')
# Create a text/plain message
msg = MIMEText(fp.read())
fp.close()
# me == the sender's email address
# you == the recipient's email address
msg['Subject'] = 'The contents of %s' % textfile
msg['From'] = me
msg['To'] = you
# Send the message via our own SMTP server, but don't include the
# envelope header.
s = smtplib.SMTP('localhost')
s.sendmail(me, [you], msg.as_string())
s.quit()
请注意,这需要您正确设置 sendmail/mailx 以接受“localhost”上的连接。默认情况下,这适用于我的 Mac、Ubuntu 和 Redhat 服务器,但您可能需要仔细检查是否遇到任何问题。
评论
localhost
Jim 的回答在 Python 3.4 中对我不起作用。我不得不添加一个额外的参数universal_newlines=True
subrocess.Popen()
from email.mime.text import MIMEText
from subprocess import Popen, PIPE
msg = MIMEText("Here is the body of my message")
msg["From"] = "[email protected]"
msg["To"] = "[email protected]"
msg["Subject"] = "This is the subject."
p = Popen(["/usr/sbin/sendmail", "-t", "-oi"], stdin=PIPE, universal_newlines=True)
p.communicate(msg.as_string())
没有 I getuniversal_newlines=True
TypeError: 'str' does not support the buffer interface
Python 3.5+ 版本:
import subprocess
from email.message import EmailMessage
def sendEmail(from_addr, to_addrs, msg_subject, msg_body):
msg = EmailMessage()
msg.set_content(msg_body)
msg['From'] = from_addr
msg['To'] = to_addrs
msg['Subject'] = msg_subject
sendmail_location = "/usr/sbin/sendmail"
subprocess.run([sendmail_location, "-t", "-oi"], input=msg.as_bytes())
评论