Python mailx不适用于子流程

Python mailx不适用于子流程,python,subprocess,Python,Subprocess,我可以通过在命令行中手动键入以下命令来发送电子邮件: echo "test email" | mailx -s "test email" someone@somewhere.net 我收到收件箱里的邮件,很有效 但它不适用于子流程: import subprocess recipients = ['someone@somewhere.net'] args = [ 'echo', '"%s"' % 'test email', '|', 'mailx', '-s', '"

我可以通过在命令行中手动键入以下命令来发送电子邮件:

 echo "test email" | mailx -s "test email" someone@somewhere.net
我收到收件箱里的邮件,很有效

但它不适用于子流程:

import subprocess
recipients = ['someone@somewhere.net']
args = [
    'echo', '"%s"' % 'test email', '|',
    'mailx',
    '-s', '"%s"' % 'test email',
] + recipients
LOG.info(' '.join(args))
subprocess.Popen(args=args, stdout=subprocess.PIPE).communicate()[0]
没有错误,但我从未收到收件箱中的电子邮件


有什么想法吗?

字符必须由shell解释,而不是由程序解释。您当前执行的操作类似于以下命令:

echo "test email" \| mailx -s "test email" someone@somewhere.net
也就是说,不要让shell处理
|
并将其作为字符串传递给echo

有两种方法可以解决此问题:

  • 用子进程(
    echo
    mailx
    )明确地从python启动两个命令,并将
    echo
    的输出通过管道传输到
    mailx
  • 在子流程中使用
    shell=True
    参数
第二种解决方案更简单,将导致:

import subprocess
recipients = 'someone@somewhere.net'
cmd = ('echo "%s" | mailx -s "%s"' % ('test email', 'test email')) + recipients
LOG.info(cmd)
subprocess.Popen(cmd, stdout=subprocess.PIPE, shell=True).communicate()[0]
但您应该在命令中使用完整路径,以避免可能导致安全问题的
path
环境问题(最终执行不需要的命令)