代码之家  ›  专栏  ›  技术社区  ›  Nate

通过python的sendmail发送邮件

  •  83
  • Nate  · 技术社区  · 17 年前

    如果我不想通过SMTP发送邮件,而是通过sendmail发送邮件,有没有python库封装了这个过程?

    更好的是,是否有一个好的库来抽象整个“sendmail与smtp”的选择?

    我将在一堆unix主机上运行此脚本,其中只有一些主机在localhost:25上监听;其中一些是嵌入式系统的一部分,无法设置为接受SMTP。

    作为良好实践的一部分,我真的很想让库自己处理头注入漏洞——所以只需将字符串转储到 popen('/usr/bin/sendmail', 'w') 比我想要的更接近金属。

    如果答案是“去写一个图书馆”,那就这样吧;-)

    8 回复  |  直到 17 年前
        1
  •  128
  •   Nebulosar Nutcracker    4 年前

    邮件头注入不是您发送邮件的一个因素,而是您构建邮件的一种因素。检查 email 打包,用它构造邮件,序列化,并将其发送到 /usr/sbin/sendmail 使用 subprocess 模块:

    import sys
    from email.mime.text import MIMEText
    from subprocess import Popen, PIPE
    
    
    msg = MIMEText("Here is the body of my message")
    msg["From"] = "me@example.com"
    msg["To"] = "you@example.com"
    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())
    
        2
  •  37
  •   Pieter    17 年前

    这是一个简单的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" % "from@somewhere.com")
        p.write("To: %s\n" % "to@somewhereelse.com")
        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
    
        3
  •  12
  •   MEI    9 年前

    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"] = "me@example.com"
    msg["To"] = "you@example.com"
    msg["Subject"] = "This is the subject."
    p = Popen(["/usr/sbin/sendmail", "-t", "-oi"], stdin=PIPE, universal_newlines=True)
    p.communicate(msg.as_string())
    

    没有 universal_newlines=真 我明白了

    TypeError: 'str' does not support the buffer interface
    
        4
  •  5
  •   Gert van den Berg    7 年前

    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())
    
        5
  •  4
  •   Robin Stewart    5 年前

    这个问题很古老,但值得注意的是,有一个名为 Marrow Mailer (以前是TurboMail),在询问此消息之前就已经可用。

    它现在正在被移植以支持Python 3,并作为Python 3的一部分进行更新 Marrow 一套。

        6
  •  3
  •   tovare    10 年前

    使用os.popen从Python中使用sendmail命令是很常见的

    就我个人而言,对于我自己没有编写的脚本,我认为只使用SMTP协议更好,因为它不需要安装sendmail克隆来在windows上运行。

    https://docs.python.org/library/smtplib.html

        7
  •  -3
  •   elec3647    12 年前

    我只是在搜索同样的东西,在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服务器,但如果遇到任何问题,您可能需要仔细检查。

        8
  •  -7
  •   user229044    14 年前

    最简单的答案是smtplib,你可以找到它的文档 here .

    您需要做的就是配置本地sendmail以接受来自localhost的连接,默认情况下它可能已经这样做了。当然,您仍然使用SMTP进行传输,但它是本地sendmail,这与使用命令行工具基本相同。