¿Cómo replicar el comportamiento de tee en Python cuando se usa el subproceso?

Estoy buscando una solución de Python que me permita guardar la salida de un comando en un archivo sin ocultarlo de la consola.

FYI: estoy preguntando sobretee (como la utilidad de línea de comandos de Unix) y no la función con el mismo nombre del módulo de herramientas de Python.

DetallesSolución Python (sin llamartee, no está disponible en Windows)No necesito proporcionar ninguna entrada a stdin para el proceso llamadoNo tengo control sobre el programa llamado. Todo lo que sé es que generará algo en stdout y stderr y regresará con un código de salida.Para trabajar al llamar a programas externos (subproceso)Para trabajar para ambosstderr ystdoutSer capaz de diferenciar entre stdout y stderr porque es posible que quiera mostrar solo uno de ellos en la consola o podría intentar generar stderr con un color diferente; esto significa questderr = subprocess.STDOUT no trabajará.Salida en vivo (progresiva): el proceso puede ejecutarse durante mucho tiempo y no puedo esperar a que termine.Código compatible con Python 3 (importante)Referencias

Aquí hay algunas soluciones incompletas que encontré hasta ahora:

http://devlishgenius.blogspot.com/2008/10/logging-in-real-time-in-python.html (mkfifo solo funciona en Unix)http://blog.kagesenshi.org/2008/02/teeing-python-subprocesspopen-output.html (no funciona en absoluto)

Diagrama http://blog.i18n.ro/wp-content/uploads/2010/06/Drawing_tee_py.png

Código actual (segundo intento)
#!/usr/bin/python
from __future__ import print_function

import sys, os, time, subprocess, io, threading
cmd = "python -E test_output.py"

from threading import Thread
class StreamThread ( Thread ):
    def __init__(self, buffer):
        Thread.__init__(self)
        self.buffer = buffer
    def run ( self ):
        while 1:
            line = self.buffer.readline()
            print(line,end="")
            sys.stdout.flush()
            if line == '':
                break

proc = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
stdoutThread = StreamThread(io.TextIOWrapper(proc.stdout))
stderrThread = StreamThread(io.TextIOWrapper(proc.stderr))
stdoutThread.start()
stderrThread.start()
proc.communicate()
stdoutThread.join()
stderrThread.join()

print("--done--")

#### test_output.py ####

#!/usr/bin/python
from __future__ import print_function
import sys, os, time

for i in range(0, 10):
    if i%2:
        print("stderr %s" % i, file=sys.stderr)
    else:
        print("stdout %s" % i, file=sys.stdout)
    time.sleep(0.1)
Salida real
stderr 1
stdout 0
stderr 3
stdout 2
stderr 5
stdout 4
stderr 7
stdout 6
stderr 9
stdout 8
--done--

La salida esperada era tener las líneas ordenadas. Observación, no está permitido modificar el Popen para usar solo un PIPE porque en la vida real querré hacer cosas diferentes con stderr y stdout.

Además, incluso en el segundo caso, no pude obtener tiempo real, de hecho, todos los resultados se recibieron cuando terminó el proceso. Por defecto, Popen no debe usar buffers (bufsize = 0).

Respuestas a la pregunta(7)

Su respuesta a la pregunta