2012-11-15 47 views
16

所以我注意到它在等待命令完成之前继续执行python脚本,我没有办法获得标准输出,除了subprocess.Popen。是否有任何其他函数调用会等到它完成? (我也试过Popen.waitPython subprocess.call和subprocess.Popen stdout

注:我试图避免os.system呼叫

result = subprocess.Popen([commands..., 
         self.tmpfile.path()], stdout=subprocess.PIPE, stderr=subprocess.PIPE) 
out, err = result.communicate() 
print out+"HIHIHI" 

我的输出:

HIHIHI 

注意:我试图运行wine与此有关。

+1

* subprocess.call()*可用于读出/ err。 [请检查手册](http://docs.python.org/2/library/subprocess.html)。确保该命令不会产生大量输出。 – tuxuday

回答

46

虽然您可能想要避免shell=True,但我正在使用以下构造。这给你的任何命令的输出和错误信息,错误代码以及:

process = subprocess.Popen(cmd, shell=True, 
          stdout=subprocess.PIPE, 
          stderr=subprocess.PIPE) 

# wait for the process to terminate 
out, err = process.communicate() 
errcode = process.returncode 
+0

我试过了,我仍然得到空的结果:s不完全确定我做错了什么。 –

+2

'cmd'的内容是什么? – Alex

+0

@Alex cmd必须是您要执行的命令。 – NeoMorfeo

10

如果你的过程给出了一个巨大的stdout和无标准错误,communicate()可能是错误的路要走由于内存限制。

相反,

process = subprocess.Popen(cmd, shell=True, 
          stdout=subprocess.PIPE, 
          stderr=subprocess.PIPE) 

# wait for the process to terminate 
for line in process.stdout: do_something(line) 
errcode = process.returncode 

可能是要走的路。

process.stdout是一个类似文件的对象,你可以把任何其他这样的对象,主要是:

  • 可以read()从中
  • 可以readline()从它和
  • 你可以遍历它。

后者是我上面做的,以便逐行获取其内容。

+1

你能向我解释for循环的用途吗? –

+0

@ Stupid.Fat.Cat它读取由进程逐行生成的'stdout'并处理每一行。 – glglgl

+0

我得到'ValueError:在关闭文件上的I/O操作'为'process.stdout中的行操作' – Yash89

11
subprocess.check_output(...) 

调用进程,如果其错误代码为非零则引发,否则返回其stdout。这只是一个快捷的速记,所以你不必担心PIPE和事情。

+0

这有问题'酒'我相信。对不起,我会将其添加到我的问题中。 –

+3

这是一个很棒的功能,只是在Python 2.7或更新版本中。 – Gourneau

1

我想尝试这样的:

#!/usr/bin/python 
from __future__ import print_function 

import shlex 
from subprocess import Popen, PIPE 

def shlep(cmd): 
    '''shlex split and popen 
    ''' 
    parsed_cmd = shlex.split(cmd) 
    ## if parsed_cmd[0] not in approved_commands: 
    ## raise ValueError, "Bad User! No output for you!" 
    proc = Popen(parsed_command, stdout=PIPE, stderr=PIPE) 
    out, err = proc.communicate() 
    return (proc.returncode, out, err) 

...换句话说让shlex.split()做的大部分工作。我不会尝试解析shell的命令行,找到管道操作员并设置自己的管道。如果你打算这么做,那么你基本上必须编写一个完整的shell语法分析器,最终你会做很多管道工作。

当然,这提出了一个问题,为什么不使用POPEN壳=真(关键字)选项?这可以让你传递一个字符串(不分割也不解析)到shell中,并且仍然收集结果,以便随意处理。我的例子在这里不会处理可能在命令中的任何流水线,反引号,文件描述符重定向等,它们都将显示为命令的文字参数。因此,它仍然更安全,然后运行shell = True ...我已经给出了一个愚蠢的例子,检查命令对某种“批准的命令”字典或设置 - 通过它会更有意义将其规范化为绝对路径,除非您打算要求参数在将命令字符串传递给此函数。

+0

我喜欢这个例子,提请注意shlex作为解析命令行输入的正确方法。幽默在这个例子中也是(shlep()和异常评论)。 :) –

相关问题