Как я могу заставить эти два процесса (программы) общаться друг с другом напрямую, используя каналы?

Программа A — это программа c, которая бесконечно получает ввод на стандартный ввод, обрабатывает его и выводит на стандартный вывод.

Я хочу написать программу B (на питоне), чтобы она считывала вывод A и возвращала все, что нужно. Обратите внимание, что должен быть только один экземпляр каждой из этих программ, поэтому заданы b1 и b2, которые являются экземплярами b вместо:

$ b1 | a | b2

мне нужно иметь

$ b1 | a | b1 

Ниже приведена диаграмма конечного желаемого результата:

альтернативный текст


person Tzury Bar Yochay    schedule 09.12.2010    source источник
comment
Какое условие остановки? Как вы определили, если ваши программы не записывают на диск или не выводят в stderr, они будут продолжать бесконечно повторяться до тех пор, пока не будет задан часовой, такой как EOF или SIGINT.   -  person MrGomez    schedule 09.12.2010
comment
@MrGomez, не беспокойтесь об этом. quit можно передать через стандартный ввод. кроме того, они предназначены для бесконечной работы ;-)   -  person Tzury Bar Yochay    schedule 09.12.2010


Ответы (2)


Используйте класс subprocess.Popen, чтобы создать подпроцесс для программы A. Например:

import subprocess
import sys

# Create subprocess with pipes for stdin and stdout
progA = subprocess.Popen("a", stdin=subprocess.PIPE, stdout=subprocess.PIPE)

# Reassign the pipes to our stdin and stdout
sys.stdin = progA.stdout
sys.stdout = progA.stdin

Теперь два процесса могут обмениваться данными друг с другом через каналы. Также может быть хорошей идеей сохранить исходные sys.stdin и sys.stdout в другие переменные, чтобы, если вы когда-нибудь решите завершить подпроцесс, вы могли восстановить стандартный ввод и стандартный вывод в исходное состояние (например, терминал).

person Adam Rosenfield    schedule 09.12.2010
comment
Я бы пропустил назначения sys.std*, просто использовал объекты progA.stdout и ProgA.stdin напрямую. Таким образом, вы не потеряете стандартный вывод. - person Winston Ewert; 09.12.2010
comment
это переназначение - это часть, которую я пропустил. огромное спасибо! (нужно подождать 8 минут, чтобы пометить ваш ответ как принятый ответ) - person Tzury Bar Yochay; 09.12.2010
comment
@Winston Ewert: Я согласен, это, вероятно, лучший вариант, но, поскольку OP потратил время на создание такой красивой диаграммы, у него, вероятно, есть веская причина для переназначения stdin и stdout. - person Adam Rosenfield; 09.12.2010

Для тех, кто приходит сюда через Google: на самом деле есть очень хороший способ использования именованных каналов:

сначала создайте 2 канала имен:

mkfifo pipe1
mkfifo pipe2

затем запустите это:

echo -n x | cat - pipe1 > pipe2 & cat <pipe2 > pipe1

это заставит команды cat постоянно копировать букву x друг в друга. Так что теперь вы можете свободно использовать свои собственные программы вместо cat для обработки ввода и вывода. Это не ограничивается питоном. Вы также можете соединить программу Java с программой C++.

Например, если ваши программы называются A.py и B.py, исходная команда будет такой:

echo -n x | ./A.py - pipe1 > pipe2 & ./B.py <pipe2 > pipe1
person Kenyakorn Ketsombut    schedule 22.01.2013