views:

52

answers:

2

I'm getting a slightly weird result from calling subprocess.Popen that I suspect has a lot to do with me being brand-new to Python.

args = [ 'cscript', '%USERPROFILE%\\tools\\jslint.js','%USERPROFILE%\\tools\\jslint.js' ]
p = Popen(args, stdout=PIPE, shell=True).communicate()[0]

Results in output like the following (the trailing double \r\n is there in case it's important)

Microsoft (R) Windows Script Host Version 5.8
Copyright (C) Microsoft Corporation. All rights reserved.\r\n\r\n

If I run that command from an interactive Python shell it looks like this

>>> args = ['cscript', '%USERPROFILE%\\tools\\jslint.js', '%USERPROFILE%\\tools\jslint.js']
>>> p = subprocess.Popen(args, stdout=subprocess.PIPE, shell=True).communicate()[0]
Lint at line 5631 character 17: Unexpected /*member 'OpenTextFile'.
f = fso.OpenTextFile(WScript.Arguments(0), 1),

...

Lint at line 5649 character 17: Unexpected /*member 'Quit'.
WScript.Quit(1);

So there's all the output I really care about, but if I dump the value of the "p" variable I just set up...

>>> p
'Microsoft (R) Windows Script Host Version 5.8\r\nCopyright (C) Microsoft Corpor
ation. All rights reserved.\r\n\r\n'
>>>

Where'd all that data I want end up going? It definitely didn't end up in "p". Looks like it's going to stdout, but I didn't I explictly tell it not to do that?

I'm running this on Windows 7 x64 with Python 2.6.6

+2  A: 

Is it going to stderr? Try redirecting:

p = subprocess.Popen(args, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, shell=True).communicate()[0]
SimonJ
it should be `p,e = Popen(...).communicate()` otherwise you're dumping stderr away
Lie Ryan
Not the way I wrote it - stderr is being redirected to stdout. You need to specify `stderr=subprocess.PIPE` if you want separate streams.
SimonJ
If I just called .communicate() w/o redirecting stderr it wasn't in the tuple I got back. Redirecting stderr did the trick though, thanks @SimonJ!
Tivac
+2  A: 

It's probably going to stderr, as SimonJ suggested.

Also, the docs say not to use shell=True in Windows for your case:

The executable argument specifies the program to execute. It is very seldom needed: Usually, the program to execute is defined by the args argument. If shell=True, the executable argument specifies which shell to use. On Unix, the default shell is /bin/sh. On Windows, the default shell is specified by the COMSPEC environment variable. The only reason you would need to specify shell=True on Windows is where the command you wish to execute is actually built in to the shell, eg dir, copy. You don’t need shell=True to run a batch file, nor to run a console-based executable.


Later: oh wait. Are you using the shell to get those environment variables expanded? Okay, I take it back: you do need the shell=True.

hughdbrown