Как повторить поведение тройника в Python при использовании подпроцесса?

Я ищу решение Python, которое позволит мне сохранить вывод команды в файл, не скрывая его от консоли.

К вашему сведению: я спрашиваю отройник (как утилита командной строки Unix), а не функция с тем же именем из модуля Python Intertools.

подробностиРешение Python (не вызываяtee, это не доступно под Windows)Мне не нужно предоставлять ввод в stdin для вызываемого процессаУ меня нет контроля над вызываемой программой. Все, что я знаю, это то, что он выведет что-то в stdout и stderr и вернет с кодом выхода.Работать при вызове внешних программ (подпроцесс)Работать для обоихstderr а такжеstdoutВозможность различать stdout и stderr, потому что я могу отображать только один из них на консоли, или я могу попытаться вывести stderr, используя другой цвет - это означает, чтоstderr = subprocess.STDOUT не будет работать.Оперативный вывод (прогрессивный) - процесс может продолжаться долго, и я не могу дождаться его завершения.Python 3 совместимый код (важно)Рекомендации

Вот некоторые неполные решения, которые я нашел до сих пор:

http://devlishgenius.blogspot.com/2008/10/logging-in-real-time-in-python.html (mkfifo работает только на Unix)http://blog.kagesenshi.org/2008/02/teeing-python-subprocesspopen-output.html (не работает вообще)

Диаграмма http://blog.i18n.ro/wp-content/uploads/2010/06/Drawing_tee_py.png

Текущий код (вторая попытка)
#!/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)
Реальный выход
stderr 1
stdout 0
stderr 3
stdout 2
stderr 5
stdout 4
stderr 7
stdout 6
stderr 9
stdout 8
--done--

Ожидаемый результат должен был упорядочить строки. Заметьте, что модификация Popen для использования только одной PIPE недопустима, потому что в реальной жизни я хочу делать разные вещи с stderr и stdout.

Кроме того, даже во втором случае мне не удалось получить информацию в режиме реального времени, фактически все результаты были получены после завершения процесса. По умолчанию Popen не должен использовать буферы (bufsize = 0).

Ответы на вопрос(7)

Ваш ответ на вопрос