user1352650
user1352650

Reputation: 121

Subprocess Popen not working with pythonw.exe

I want to be able to get the contents of stdout and stderr when I run the following script on windows using pythonw.exe:

import subprocess
import sys
import os
import string
import time

tmpdir = 'c:/temp'
cmd = 'dir c:'

tmpfile = "tmp_%f" % (time.time())
tmpfile = os.path.normpath(os.path.join(tmpdir,tmpfile))
tmpfile2 = tmpfile+".bat"
tmpfile3 = tmpfile+".txt"

fa = open(tmpfile2,'w')
fa.write("@ECHO OFF > NUL\n")
fa.write('call '+cmd+"\n")
fa.close()

wcmd = []
wcmd.append(tmpfile2)

startupinfo = subprocess.STARTUPINFO()
startupinfo.dwFlags |= subprocess._subprocess.STARTF_USESHOWWINDOW

fb = open(tmpfile3,'w')
fb.write("\n")
fb.write(tmpfile2+"\n")

try:
    procval = subprocess.Popen(wcmd, startupinfo=startupinfo, stdout=subprocess.PIPE, stderr=subprocess.STDOUT).communicate()
    fb.write(str(procval)+"\n")
    fb.write("Sucess")
    fb.close()
except:
    fb.write(str(procval)+"\n")
    fb.write("Failure")
    fb.close()

When I execute it using python.exe I get the expected output. When I run it using pythonw.exe I end up on the exception side. If I run the popen with just the command and the startupinfo flags the command will successfully complete but no access to the data in the child processs. Everything that I read stated that this should work but must be missing something. Any help would be greatly appreciated.

Thanks, Randy

Upvotes: 12

Views: 4399

Answers (2)

jdigital
jdigital

Reputation: 12296

(A few years late with this answer...) I've run across the same problem and found that you should replace this:

stdout=subprocess.PIPE

with this:

stdin=subprocess.PIPE

Here's my guess at the underlying problem: pythonw launches the process with no stdin (makes sense, since there is no console). The sub-process tries to access stdin and this causes an error.

An alternative is to use /dev/null for stdin, see this thread for a discussion on how to do that: Ignoring output from subprocess.Popen (except you'll want to use devnull on stdin).

Upvotes: 4

jdi
jdi

Reputation: 92647

This is possibly a bug when using pythonw.exe

pythonw.exe starts a daemon process which doesn't have the normal access to the standard file descriptors. The only thing you would need to do in your script is to specifically set the 3rd fd for stdin:

p = subprocess.Popen(wcmd,
                     startupinfo=startupinfo,
                     stdout=subprocess.PIPE,
                     stderr=subprocess.STDOUT,
                     stdin=subprocess.PIPE)
procval = p.communicate()

Upvotes: 11

Related Questions