1

i try to rewrite popen2 to subprocess.Popen. And I get error.

My code:

cmd = '/usr/sbin/sendmail -t -i'
if len(sys.argv) == 3:
  cmd += " -f%s" % sys.argv[2]

# OLD CODE =======================
#(out, s) = popen2(cmd)
#s.write(data)
#s.close()
# ================================

# NEW CODE =======================

p = Popen(cmd, shell=True, stdin=PIPE, stdout=PIPE, close_fds=True)
(out, s) = (p.stdin, p.stdout)
s.write(data)
s.close()
sys.stdout.flush()

In apache error_log I get error:

Traceback (most recent call last):
  File "/opt/php-secure-sendmail/secure_sendmail.py", line 80, in <module>
    s.write(data)
IOError: File not open for writing
sendmail: fatal: test@serve.tld(10000): No recipient addresses found in message header
plesk sendmail[2576]: sendmail unsuccessfully finished with exitcode 75

Maybe somebody has idea how figure out this code?

outofstack
  • 13
  • 4
  • http://stackoverflow.com/questions/4744133/no-recipient-addresses-found-in-header your email content must be wrong so that get the error – lqhcpsgbl Jan 23 '15 at 09:39

2 Answers2

0

You're trying to write on stdout which is open only for reading.

stdout contains the printed output of the new process, you must write to stdin to send it data.

popen2 is returning a tuple (stdout, stdin), that's why the commented code works. https://docs.python.org/2/library/popen2.html

Just invert the order in your tuple and it will work:

p = Popen(cmd, shell=True, stdin=PIPE, stdout=PIPE, close_fds=True)
(out, s) = (p.stdout, p.stdin)
s.write(data)
s.close()
sys.stdout.flush()
noxdafox
  • 14,439
  • 4
  • 33
  • 45
  • so please tag the answer as correct so the question will appear as solved and will help other people. To do so just click on the arrow up nearby it. – noxdafox Jan 26 '15 at 13:10
0

You could use .communicate() method to pass data to the child process:

cmd = '/usr/sbin/sendmail -t -i'.split()
if len(sys.argv) > 2:
  cmd += ["-f", sys.argv[2]]
p = Popen(cmd, stdin=PIPE, close_fds=True)
p.communicate(data)

Notice that you don't need shell=True here.

I've removed stdout=PIPE because I don't see the output used in your code. If you want to suppress the output; see How to hide output of subprocess in Python 2.7.

Community
  • 1
  • 1
jfs
  • 399,953
  • 195
  • 994
  • 1,670