2010-10-16 69 views
2

我从调用subprocess.Popen中得到一个稍微奇怪的结果,我怀疑这个结果与我对Python的全新使用有很大关系。从子流程中获取整个输出.Popen

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

结果输出如下(后双\ r \ n是有它的重要情况)

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

如果我运行从一个交互式的Python是命令外壳,它看起来像这样

>>> 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); 

所以这是所有输出我很在意,但如果我甩我刚刚成立的“p”变量的值...

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

哪里有我想要的所有数据?它绝对没有以“p”结尾。看起来它将会stdout,但我没有明确地告诉它不这样做?

我的Windows 7 64位与Python 2.6.6

回答

5

运行,这是它要标准错误?尝试重定向:

p = subprocess.Popen(args, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, shell=True).communicate()[0] 
+0

它应该是'p,e = Popen(...)。沟通()'否则你就是把stderr扔掉 – 2010-10-16 01:31:49

+2

不是我写它的方式 - stderr被重定向到stdout。如果你需要单独的流,你需要指定'stderr = subprocess.PIPE'。 – SimonJ 2010-10-16 01:39:02

+1

如果我只是调用.communicate()w/o重定向标准错误,它不在我回来的元组中。重定向stderr虽然做了,但谢谢@SimonJ! – Tivac 2010-10-16 02:03:11

3

正如SimonJ建议的那样,它可能会去stderr

此外,docs都说不要使用Windows shell=True为您的情况:

可执行参数指定 程序来执行。很少需要 :通常, 执行的程序由args 参数定义。如果shell = True,则 可执行参数将指定要使用哪个shell的 。在Unix上,默认的 shell是/ bin/sh。在Windows上, 默认外壳由 COMSPEC环境变量指定。唯一需要指定的 原因 在Windows上,shell = True是您要执行的命令 实际内置于shell中的位置,例如 dir,copy。您不需要shell = True 来运行批处理文件,也不需要运行基于控制台的可执行文件 。


后来:哦,等等。你使用shell来扩展这些环境变量吗?好的,我收回:您确实需要shell=True