如何使用Python调用命令,捕获stderr和stdout,而无需等待stderr /
现在我有一些代码使用来自子进程的
Popen.communicate() (设置stdin = PIPE和stderr = PIPE)来运行命令并捕获stderr和stdout.
问题是communication()不仅等待命令退出,还等待stdout和stderr关闭.我正在运行的命令会生成一个子进程,它会使stderr保持打开状态,所以即使命令运行完毕(并在ps中显示为“defunct”),仍然会挂起(). 我想只等待命令完成而不等待stderr / stdout.但我仍然希望捕获命令运行时给出的任何stderr / stdout输出. The documentation for
显然,我也想避免陷入僵局. 完成这项任务的正确方法是什么? 解决方法
“在ps中显示为”defunct“意味着您可能在select或fcntl可以工作的系统上,即,您可以轻松地读取stdout / stderr.
示例:A启动B(cmd,孩子),B启动C(孙子),A读取输出直到B退出或EOF: #!/usr/bin/env python import os from select import select from subprocess import Popen,PIPE p = Popen(cmd,stdout=PIPE,stderr=PIPE,bufsize=0) read_set = [p.stdout,p.stderr] pipename = {p.stdout: "stdout",p.stderr: "stderr"} timeout = 0.5 # ugly but it works while read_set and p.poll() is None: # while subprocess is running or until EOF for pipe in select(read_set,[],timeout)[0]: data = os.read(pipe.fileno(),1<<30) if data: print("got from %s: %r" % (pipename[pipe],data)) else: # EOF pipe.close() read_set.remove(pipe) print("exit code %s" % (p.wait(),)) # child exited,wait for grandchild to print for pipe in read_set: print("read the rest of %s: %r" % (pipename[pipe],pipe.read())) pipe.close() 其中cmd: import sys from textwrap import dedent cmd = [sys.executable,'-u','-c',dedent(""" # inception style import os import sys from subprocess import Popen from textwrap import dedent Popen([sys.executable,dedent(''' import os import sys import time time.sleep(60) print("grandchild %d done" % os.getpid()) sys.stderr.write("grandchild stderr") sys.exit(20) ''')]) # stdout/stderr are not redirected print('child %d done' % os.getpid()) sys.stderr.write('child stderr') sys.exit(19) """)] (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |