Como replicar o comportamento do tee em Python ao usar o subprocesso?

Estou procurando uma solução Python que permita salvar a saída de um comando em um arquivo sem ocultá-lo do console.

FYI: Estou perguntando sobretee (como o utilitário de linha de comando Unix) e não a função com o mesmo nome do módulo intertools do Python.

DetalhesSolução Python (não chamandotee, não está disponível no Windows)Não preciso fornecer nenhuma entrada para o stdin para o processo chamadoNão tenho controle sobre o programa chamado. Tudo o que sei é que ele produzirá algo para stdout e stderr e retornará com um código de saída.Para trabalhar ao chamar programas externos (subprocesso)Para trabalhar para ambosstderr estdoutSer capaz de diferenciar entre stdout e stderr, porque talvez eu queira exibir apenas uma delas no console ou tente produzir o stderr usando uma cor diferente - isso significa questderr = subprocess.STDOUT não funciona.Saída ao vivo (progressiva) - o processo pode ser executado por um longo período de tempo, e não posso esperar que ele termine.Código compatível com Python 3 (importante)Referências

Aqui estão algumas soluções incompletas que encontrei até agora:

http://devlishgenius.blogspot.com/2008/10/logging-in-real-time-in-python.html (mkfifo funciona apenas em Unix)http://blog.kagesenshi.org/2008/02/teeing-python-subprocesspopen-output.html (não funciona)

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

Código atual (segunda tentativa)
#!/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)
Saída real
stderr 1
stdout 0
stderr 3
stdout 2
stderr 5
stdout 4
stderr 7
stdout 6
stderr 9
stdout 8
--done--

A saída esperada era ordenar as linhas. Nota, modificar o Popen para usar apenas um PIPE não é permitido, porque na vida real eu vou querer fazer coisas diferentes com stderr e stdout.

Também, mesmo no segundo caso, não consegui obter uma saída em tempo real, de fato, todos os resultados foram recebidos quando o processo terminou. Por padrão, o Popen não deve usar buffers (bufsize = 0).

questionAnswers(7)

yourAnswerToTheQuestion