I have made some tests to redirect stdout during long process.
I have got some result that I don't understand.
run.py
import contextlib
import subprocess
import sys
newlines = ['\n', '\r\n', '\r']
def example1():
#stupid test, for fun
cmd = ['python', 'in.py']
proc = subprocess.Popen(
cmd,
stdout=sys.stdout,
stderr=sys.stderr,
)
def example2():
# http://stackoverflow.com/questions/803265/getting-realtime-output-using-subprocess
def unbuffered(proc, stream='stdout'):
stream = getattr(proc, stream)
while True:
out = []
last = stream.read(1)
# Don't loop forever
if last == '' and proc.poll() is not None:
break
while last not in newlines:
# Don't loop forever
if last == '' and proc.poll() is not None:
break
out.append(last)
last = stream.read(1)
out = ''.join(out)
print(out)
cmd = ['python', 'in.py']
proc = subprocess.Popen(
cmd,
stdout=subprocess.PIPE,
stderr=subprocess.STDOUT,
# Make all end-of-lines '\n'
universal_newlines=True,
)
for line in unbuffered(proc):
print(line)
def example3():
#http://stackoverflow.com/questions/4417546/constantly-print-subprocess-output-while-process-is-running
cmd = ['python', 'in.py']
popen = subprocess.Popen(cmd, stdout=subprocess.PIPE)
lines_iterator = iter(popen.stdout.readline, b"")
while popen.poll() is None:
for line in lines_iterator:
nline = line.rstrip()
print(nline.decode("latin"), end="\r\n",flush=True)
in.py
import random
import sys
import time
END = 10
for i in range(END):
print(i)
if i == random.randint(1, END-2):
sys.stderr.write('Error, out !!!\n')
sys.exit(i)
time.sleep(0.2)
example1:
Surprise... I can redirect the stdout to the console (doesn't work with bpython). Weirdly I must press a key to finish the process.
example2 and example3:
Output print only at the sub-process end.
I'm fairly new in subprocessing, thanks for any explanation. :)