У меня есть 5 процессов p1,p2,...,p5
, в которых я хочу записать некоторые данные на стандартный ввод p1, передать вывод p1 на стандартный ввод p2 и, наконец, прочитать окончательный результат с вывода p5.
Что я пробовал до сих пор:
p1 = Popen(['p1'], stdin=PIPE, stdout=PIPE)
p2 = Popen(['p2'], stdin=p1.stdout, stdout=PIPE)
...
p5 = Popen(['p5'], stdin=p4.stdout, stdout=PIPE)
# write data to stdin
p1.stdin.write(indata)
p1.stdin.close()
# not sure in what order to close the pipes here, if at all
# read output
out = p5.stdout.read()
print out
Последний отрезанный код просто зависает, потому что я, должно быть, неправильно выполняю операции чтения/записи.
Мне удалось получить работающие отдельные процессы, используя communicate()
и два процесса, не вводя никаких входных данных для первого (пример из документации Python):
output=`dmesg | grep hda`
==>
p1 = Popen(["dmesg"], stdout=PIPE)
p2 = Popen(["grep", "hda"], stdin=p1.stdout, stdout=PIPE)
p1.stdout.close() # Allow p1 to receive a SIGPIPE if p2 exits.
output = p2.communicate()[0]
Но я не могу понять, как ввести данные в первый процесс, не зависая интерпретатор.
Я также мог бы использовать для этого сценарий bash (который я уже написал и работает), но я хотел бы знать, как добиться того же с помощью Python.
Итак, я хотел бы спросить, как все это сделать правильно, в частности, в каком порядке выполнять операции чтения/записи/закрытия каналов?
Я работаю над 64-битным Linux, если это имеет значение.
РЕДАКТИРОВАТЬ: я забыл упомянуть, что все процессы p1,..p5 потребляют все вводимые данные, обрабатывают их, записывают в стандартный вывод и затем завершают работу. Таким образом, процессы, следующие в конвейере, не должны завершаться до завершения обработки предыдущих.
EDIT2: я знаю, что также мог бы использовать
command = 'bash -c "p1 | p2 | p3 | p4 | p5"'
proc = Popen([command], shell=True)
out, err = proc.communicate(input=indata)
print out
но мой главный интерес - узнать, как связать каналы исключительно в коде Python.
subprocess
(например, sam.nipl.net/code/python/ pipe.py из комментария к другому ответу), по-видимому, подвержены странным ошибкам. - person Kyle Strand   schedule 04.12.2014pipes
(docs.python.org/2 /library/pipes.html) и соответственно добавил ответ на другой вопрос. Это выглядит намного лучше, чем другие решения. - person Kyle Strand   schedule 04.12.2014