【问题标题】:Send mail with newline and Linux mail command via Pythons subprocess通过 Python 子进程使用换行符和 Linux 邮件命令发送邮件
【发布时间】:2019-11-24 15:08:42
【问题描述】:

我想使用用户名和随机生成的密码生成帐户。 然而。我无法发送多行邮件。 显示我的问题的最小代码是:

import subprocess
import string

username = Test
randomPassword = abcabc
fromAddr='test@example.com'
toAddr='receive@example.com'
subject='Test Mail'
body='Your Username is ' + username + '\n'+'Your Password is' + randomPassword
cmd='echo '+body+' | mail -s '+subject+' -r '+fromAddr+' '+toAddr
send=subprocess.call(cmd,shell=True)

错误是:

mail: cannot send message: process exited with a non-zero status

/var/log/mail.err 显示如下

[SERVERNAME] sSMTP[9002]: RCPT TO:<[SUBJECT]@[SERVERNAME]> (Domain does not exist: [SERVERNME])

我发现的一个建议是使用

cmd='echo -e ' +body+ [...] 

但这并没有解决问题。

有什么建议吗?

【问题讨论】:

  • 为什么不使用 Python 库来发送邮件?
  • 有一个我们想要使用的已设置邮件服务器,因此我们只需更改 ssmtp 配置中的设置,一切都可以正常运行。我更喜欢使用 Linux 邮件命令。但是,如果使用该方法无法做到这一点,我也可以使用 python 库

标签: python linux bash unix


【解决方案1】:

您需要将正文和主题放在引号中。如果你使用 f-string 会更容易

cmd  = f"echo '{body}' | mail -s '{subject}' -r '{fromAddr}' '{toAddr}'"

请注意,您需要确保任何参数中都没有引号字符——确保您不允许密码中出现单引号。

【讨论】:

  • 我无法编辑它。但在 {toAddr} 之后有一个 ' 缺失。所以正确的命令是: cmd = f"echo '{body}' | mail -s '{subject}' -r '{fromAddr}' '{toAddr}'" 但是这个解决方案就像一个魅力。谢谢你。一旦 StackOverflow 允许我将标记为正确答案
  • @ChrizZ 你应该看看三胞胎的答案,比这个更好。
  • 您可以使用shlex 解决引用问题,但它变得足够复杂,可能仍会引入漏洞;还有其他原因要避免使用shell=True - 请参阅Actual meaning of shell=True in subprocess
【解决方案2】:

您确实想避免 Barmar 的回答出现各种引用问题。如果你的 Python 足够新,你想要

send = subprocess.call(
    ['mail', '-s', subject, '-r', fromAddr, toAddr],
    input=body, text=True)

在 Python 3.7 之前,您需要将 text=True 替换为旧的、更不清楚的别名 universal_newlines=Trueinput 参数可能是在 Python 3.3 中引入的。有关如何在旧版本中执行类似操作的 idas,以及更详细的讨论,请参阅 Running Bash commands in Python

【讨论】:

  • mailsendmail 的一个非常薄的包装器(尽管它有相当多的代码与从命令行发送消息无关)所以这基本上相当于将f'From: {fromAddr}\nTo: {toAddr}\nSubject: {subject}\n\n' 添加到body 字符串和管道到sendmail
猜你喜欢
  • 2015-03-19
  • 2015-11-27
  • 2011-02-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多