Constantly print Subprocess output while process is running
To launch programs from my Python-scripts, I'm using the following method:
def execute(command):
process = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
output = process.communicate()[0]
exitCode = process.returncode
if (exitCode == 0):
return output
else:
raise ProcessException(command, exitCode, output)
So when i launch a process like Process.execute("mvn clean install")
, my program waits until the the process is finished, and only then i get the complete output of my program. This is annoying if i'm running a process that takes a while to finish.
Can i let my program write the process output line by line, by polling the process output before it finishes in a loop or something?
**[EDIT] Sorry i didn't search very well before posting this question. Threading is actually the key. Found an example here which shows how to do it: ** Python Subprocess.Popen from a thread
You can use iter to process lines as soon as the command outputs them: lines = iter(fd.readline, "")
. Here's a full example showing a typical use case (thanks to @JF Sebastian for helping out):
from __future__ import print_function # Only Python 2.x
import subprocess
def execute(cmd):
popen = subprocess.Popen(cmd, stdout=subprocess.PIPE, universal_newlines=True)
for stdout_line in iter(popen.stdout.readline, ""):
yield stdout_line
popen.stdout.close()
return_code = popen.wait()
if return_code:
raise subprocess.CalledProcessError(return_code, cmd)
# Example
for path in execute(["locate", "a"]):
print(path, end="")
好吧,我设法解决它没有线程(任何建议,为什么使用线程会更好,赞赏)通过使用这个问题的代码片段在运行时拦截子进程的标准输出
def execute(command):
process = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
# Poll process for new output until finished
while True:
nextline = process.stdout.readline()
if nextline == '' and process.poll() is not None:
break
sys.stdout.write(nextline)
sys.stdout.flush()
output = process.communicate()[0]
exitCode = process.returncode
if (exitCode == 0):
return output
else:
raise ProcessException(command, exitCode, output)
To print subprocess' output line-by-line as soon as its stdout buffer is flushed in Python 3:
from subprocess import Popen, PIPE, CalledProcessError
with Popen(cmd, stdout=PIPE, bufsize=1, universal_newlines=True) as p:
for line in p.stdout:
print(line, end='') # process line here
if p.returncode != 0:
raise CalledProcessError(p.returncode, p.args)
Notice: you do not need p.poll()
-- the loop ends when eof is reached. And you do not need iter(p.stdout.readline, '')
-- the read-ahead bug is fixed in Python 3.
See also, Python: read streaming input from subprocess.communicate().
链接地址: http://www.djcxy.com/p/77142.html上一篇: 将子流程标准输出转换为变量
下一篇: 进程运行时不断打印子进程输出