Python子进程隐藏标准输出并等待其完成

5

我有这段代码:

def method_a(self):
    command_line = 'somtoolbox GrowingSOM ' + som_prop_path
    subprocess.Popen(shlex.split(command_line))
    ......

def method_b(self): .....
....

正如大家所看到的,method_a有一项子进程正在调用somtoolbox程序。但这个程序的stdout很长,我想隐藏它。我尝试过:

subprocess.Popen(shlex.split(command_line), stdout=subprocess.PIPE)

但是它返回了这句话:
cat: record error: Broked Pipe   

这是对葡萄牙语句子的翻译:“cat: erro de gravação: Pipe quebrado”(我来自巴西)。

此外,我还有其他方法(例如 method_b),它们在 method_a 之后被调用,并且在子进程完成处理之前运行。

我该如何完全隐藏 stdout(不想让它出现在任何地方),并使其他代码等待子进程执行完成?

注:somtoolbox 是一个 Java 程序,会向终端输出大量内容。

尝试过:

outputTuple = subprocess.Popen(shlex.split(command_line), stdout = subprocess.PIPE).communicate()

但是持续返回输出到shell。 帮帮我!
2个回答

18

最好的方法是将输出重定向到 /dev/null。你可以像这样做:

devnull = open('/dev/null', 'w')
subprocess.Popen(shlex.split(command_line), stdout=devnull)
然后要等待它完成,您可以在Popen对象上使用.wait(),使您达到以下效果:
devnull = open('/dev/null', 'w')
process = subprocess.Popen(shlex.split(command_line), stdout=devnull)
retcode = process.wait()

retcode将包含进程的返回代码。

附加说明:如评论中所述,这并不会隐藏stderr。如果要隐藏stderr,可以这样做:

devnull = open('/dev/null', 'w')
process = subprocess.Popen(shlex.split(command_line), stdout=devnull, stderr=devnull)
retcode = process.wait()

@Gabriel 也许你需要重定向 stderr 吗? - Paul Kuliniewicz
如果你用os.devnull替换'/dev/null'(自2.4版本以来就像subprocess本身一样存在),它也可以在Windows上运行。 - Stein
1
请注意,在Python 3.3+中可以使用subprocess.DEVNULL,而不是open('/dev/null', 'w') - Mark Amery

5

Popen.communicate 用于等待进程终止。例如:

from subprocess import PIPE, Popen
outputTuple = Popen(["gcc", "--version"], stdout = PIPE).communicate()

将返回一个字符串元组,一个用于标准输出,另一个用于错误输出。

它没有起作用。请看我的最后一句话,看看是否有所改变。这是一个Java程序的输出...请看那里。 - Gabriel L. Oliveira

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接