python subprocess 隐藏stdout并等待完成

5 投票
2 回答
14245 浏览
提问于 2025-04-16 00:28

我有一段代码:

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

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

正如大家所看到的,method_a 里有一个子进程在调用 somtoolbox 程序。但是这个程序的输出很长,我想把它隐藏起来。我试过:

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

但是它返回了这句话:

cat: record error: Broked Pipe   

(这是葡萄牙语句子的翻译:“cat: 错误:管道破裂”)
(我来自巴西)

另外,我还有其他方法(像 method_b),它们是在 method_a 之后被调用的,而这些方法在子进程完成之前就开始运行了。

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

备注:somtoolbox 是一个 Java 程序,它会把长输出显示在终端上。
我试过:

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

但还是不断地把输出返回到命令行。
求助!

2 个回答

5

Popen.communicate 是用来等待一个进程结束的。例如:

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

这个方法会返回一个包含两个字符串的元组,一个是标准输出(stdout),另一个是错误输出(stderr)。

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)。如果你也想隐藏错误输出,可以这样做:

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

撰写回答