Я хочу постоянно отслеживать процесс по конвейеру и печатать его stdout
и stderr
по мере его поступления (мне не интересно получать весь вывод сразу после его выхода).Проблема состоит в том, что переданный по конвейеру процесс порождает другой дочерний процесс, и stdout
и stderr
этого порожденного процесса не доступны, используя каналы исходного процесса.
А именно, я хочу запустить pythonзапрограммируйте таким образом, так что конвейерный процесс является интерпретатором python, но интерпретатор python порождает выполнение программы python в другом подпроцессе, поэтому я не могу получить вывод этого (фактический вывод программы).Если при запуске программы произошла ошибка, я могу получить ее, потому что она напечатана на оригинальном интерпретаторе Python stderr
.Но нормальное stdout
из самой программы потеряно для меня.
Я использую subprocess.Popen
.
Редактировать: комментатор попросил образец кода, я не думаю, что этомногое добавляет, но вот мой код (PopenProcess
- это интеллектуальный класс-обертка для subrpocess.Popen
, но ничего особенного не делает):
class BTask:
def __init__(self, name, cmds, color = "NONE"):
self.name = name
self.cmds = cmds
self.color = color
self.proc = None
def procreadline(self, sline):
print(ANSI[self.color] + self.name + ANSI["ENDC"] + " > " + ANSI[self.color] + sline)
def procreaderror(self, sline):
print(ANSI[self.color] + self.name + ANSI["BRIGHTWHITE"] + " ! " + ANSI["BRIGHTRED"] + sline)
def run(self):
print(ANSI["GREEN"])
print("running task: {} {}".format(ANSI["BRIGHTGREEN"], self.name))
pargs = []
if len(self.cmds) > 1:
pargs = self.cmds[1:]
print(ANSI[self.color])
self.proc = PopenProcess(
self.cmds[0],
self.procreadline,
read_error_callback = self.procreaderror,
proc_args = pargs,
ignore_cwd = True
)
def kill(self):
print(ANSI["RED"])
print("killing task: {} {}".format(ANSI["BRIGHTRED"], self.name))
self.proc.kill()
def is_alive():
return self.proc.is_alive()