Constantly print Subprocess output while process is running Constantly print Subprocess output while process is running python python

Constantly print Subprocess output while process is running


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 @jfs for helping out):

from __future__ import print_function # Only Python 2.ximport subprocessdef 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)# Examplefor path in execute(["locate", "a"]):    print(path, end="")


To print subprocess' output line-by-line as soon as its stdout buffer is flushed in Python 3:

from subprocess import Popen, PIPE, CalledProcessErrorwith Popen(cmd, stdout=PIPE, bufsize=1, universal_newlines=True) as p:    for line in p.stdout:        print(line, end='') # process line hereif 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().


Ok i managed to solve it without threads (any suggestions why using threads would be better are appreciated) by using a snippet from this question Intercepting stdout of a subprocess while it is running

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)