我正在用python构建脚本,其中一部分需要发送包含文件作为邮件正文的电子邮件。脚本不发送文件内容,而是向我发送输入到终端的下一个字符,例如如果我将c作为“ cat”的一部分输入,它不会将c放入终端,而是向我发送一封电子邮件,其中以“ c”作为正文。
这是在CentOS 7.6.1810和Python 3.5.6上。
#!/usr/src/Python-3.5.6/python
import subprocess
import sys
import os
subprocess.Popen(["mail", "-s", "Test Subject", "myemail@myemail.com", "<", "/path/to/file.txt"], stdout=open('stdout', 'w'), stderr=open('errout', 'w'))
file.txt的内容应作为正文发送,但无论输入的是下一个字母,我都会得到它的第一个字母。此后,“ stdout”读取为“ EOT”,并且没有任何内容打印到“ errout”。为了清楚起见,我正在尝试调用命令
mail -s "Test Subject" myemail@myemail.com < /path/to/file.txt
在脚本内部。该命令在Python脚本之外可以正常工作,但是在其中却遇到了问题。
答案 0 :(得分:3)
subprocess.Popen()
默认情况下直接执行新过程。因此,您的代码会将其他一些参数<
和/path/to/file.txt
传递给mail
可执行文件,这不会产生预期的结果。
在Unix系统上,像<
这样的重定向是由Shell处理的,而不是由每个可执行文件处理的。这就是为什么您希望subprocess.Popen()
在所有mail
参数和mail
重定向中在外壳程序中运行< /path/to/file.txt
命令的原因。
您可以使用shell=True
参数来完成此操作:
subprocess.Popen(["mail", "-s", "Test Subject", "myemail@myemail.com", "<", "/path/to/file.txt"], stdout=open('stdout', 'w'), stderr=open('errout', 'w'), shell=True)
请注意,shell可能不是必需的–您可以Popen
打开文件并将mail
的{{1}}连接到该描述符,请参阅下面的anishsane注释。
应避免使用外壳程序,尤其是在将用户数据传递给子进程的情况下,因为需要对其进行适当的清理以防止命令注入攻击。