2
votes

I am writing a web application that will execute a command on the local Windows server and need to display the output. The Popen() call in my code executes fine on the Python interpreter but gives a nasty error when executed via IIS. Thanks!!!!

Error text:

Traceback (most recent call last):

File "C:\pythonapps\mystdout.py", line 9, in print Popen('ipconfig', shell=True, stdout=PIPE).communicate()[0]

File "C:\Python27\lib\subprocess.py", line 672, in init errread, errwrite) = self._get_handles(stdin, stdout, stderr)

File "C:\Python27\lib\subprocess.py", line 774, in _get_handles p2cread = _subprocess.GetStdHandle(_subprocess.STD_INPUT_HANDLE)

WindowsError: [Error 6] The handle is invalid

from subprocess import *

print "Content-type:text/html\r\n\r\n"
print "<html>"
print "<head>"
print "<title>FSPCT app</title>"
print "</head>"
print "<body>"
print Popen('ipconfig', shell=True, stdout=PIPE).communicate()[0]
print "</body>"
print "</html>"
2

2 Answers

2
votes

It looks like the IIS server doesn't have a valid stdin file handle (not all that surprising, as it's a server process). The subprocess module is trying to copy that stdin file handle... and failing.

To fix this, call Popen for the subprocess you're executing with the stdin file handle (and maybe stderr too for good measure) bound to the NUL file. (os.devnull is the portable way of referring to that file in Python 2.7.) Said NUL file (or /dev/null under Unix) simply discards everything written to it, and returns end-of-file immediately when read from. Perfect for this.

Try modifying your code like this:

import os
...
with open(os.devnull, 'r+') as nul:
    print Popen('ipconfig', shell=True, stdin=nul, stdout=PIPE, stderr=nul).communicate()[0]

(In the upcoming Python 3.3, you can now pass subprocess.DEVNULL to the stdin, stdout or stderr arguments of Popen to do the same thing more concisely.)

2
votes

The default subprocess.Popen() value for stdin is None, which passes stdin from the parent process.

To use an internal stdin, just pass stdin=PIPE with your Popen() call.

print Popen('ipconfig', shell=True, stdin=PIPE, stdout=PIPE).communicate()[0]