Подтвердить что ты не робот

Как перенаправить stdout второго процесса обратно на stdin 1-го процесса?

У меня есть два процесса, которые мне нужно подключить следующим образом:

proc1 - отправляет выходные данные в proc2 proc2 - отправляет выходные данные в proc1

До сих пор все примеры труб такого типа:   proc1 | proc2

Это хорошо, но как я могу сделать вывод proc2 в proc1?

Пример bash был бы приятным. Пример оболочки Windows был бы замечательным:)

Спасибо заранее, Адриан.

Добавление более подробной информации:

Ожидается, что система будет работать как система клиент-сервер, в которой клиент работает с сервером в модели взаимодействия с запросом-ответом. Взаимодействие заканчивается, когда у клиента больше нет запросов.

Пример взаимодействия: client: request1; server: response1; client: request2; server: response2; , , , , client: closeRequest; server: closeApproved;

В этот момент сервер завершает работу после выхода клиента. Конец примера.

Похоже, что решение вроде (при условии, что канал доступен) клиент < трубы | сервеp > труба не будет работать (пожалуйста, поправьте меня), потому что в этой компоновке клиент производит один большой запрос, оболочка передает этот большой запрос серверу, затем сервер производит один большой ответ, и, наконец, оболочка передает этот большой ответ клиенту.

4b9b3361

Ответ 1

Похоже, что сопроцессор bash может быть тем, что вы хотите. Найдите coproc зарезервированное слово в руководстве bash.


(Изменить: добавление простой схемы использования)

Он работает следующим образом:

# start first process as a coprocess to the current shell
coproc proc1

# now ${COPROC[0]} contains the number of an open (input) file descriptor
# connected to the output of proc1, and ${COPROC[1]} the number of an
# open (output) file descriptor connected to the input of proc1.


# start second process, connecting its input- and outputstreams
# to the output- and inputstreams of the first process
proc2 <&${COPROC[0]} >&${COPROC[1]}

# wait on the first process to finish.
wait $COPROC_PID

Если у вас может быть несколько сопроцессов, дайте вашему процессу такое имя:

coproc NAME {
    proc1
}

Затем вы можете использовать NAME везде, где раньше использовался coproc.


Вот полная примерная программа, использующая функцию ping как proc1 и proc2:

#!/bin/bash
#
# Example program using a bash coprocess to run two processes
# with their input/output streams 
#


#
# A function which reads lines of input and
# writes them back to standard output with the
# first char cut off, waiting 5s inbetween.
#
# It finishes whenever an empty line is read or written,
# or at end-of-file.
#
# The parameter $1 is used in debugging output on stderr.
#
function ping ()
{
    while read 
    do
        local sending
        echo "ping $1: received '$REPLY'" >&2
        [[ -n $REPLY ]] || break
        sleep 5s
        sending=${REPLY:1}
        echo "ping $1: sending '$sending'"  >&2
        echo $sending
        [[ -n $sending ]] || break
    done
    echo "ping $1: end" >&2
}

#
# Start first ping process as a coprocess with name 'p1'.
#

coproc p1 {
    ping 1
}

# send some initial data to p1. (Not needed if one of the processes
# starts writing before first reading.)
echo "Hello World" >&${p1[1]}
sleep 2.5s

#
# Run second ping process, connecting its default input/output
# to the default output/input of p1.
# 
ping 2 <&${p1[0]} >&${p1[1]}

# wait for the coprocess to finish too.
wait $p1_PID

Он использует две вызовы функции оболочки вместо внешних программ, но она также будет работать с такими программами. Вот вывод (на stderr):

ping 1: received 'Hello World'
ping 1: sending 'ello World'
ping 2: received 'ello World'
ping 2: sending 'llo World'
ping 1: received 'llo World'
ping 1: sending 'lo World'
ping 2: received 'lo World'
ping 2: sending 'o World'
ping 1: received 'o World'
ping 1: sending ' World'
ping 2: received 'World'
ping 2: sending 'orld'
ping 1: received 'orld'
ping 1: sending 'rld'
ping 2: received 'rld'
ping 2: sending 'ld'
ping 1: received 'ld'
ping 1: sending 'd'
ping 2: received 'd'
ping 2: sending ''
ping 2: end
ping 1: received ''
ping 1: end

Ответ 2

вот пример bash, использующий эхо, чтобы обеспечить некоторый начальный ввод и named pipe, чтобы разрешить цикл обратной связи:

mkfifo fifo
echo "fifo forever" | cat - fifo | tee fifo
  • proc1 (cat) принимает данные от stdin и fifo
  • proc2 (tee) передает выходные данные в stdout и fifo

Ответ 3

Это пример, показывающий, что вы хотите, с двумя процессами, которые принимают один аргумент:

mkfifo fifo
./process1 argument1 < fifo | ./process2 argument1 > fifo

Сначала мы создаем именованный канал с именем fifo в текущем каталоге. Затем мы выполняем process1 с fifo как входной, выход которого будет проходить через анонимный канал | на вход process2, выход которого будет идти до fifo, закрывая цикл.

После выхода из обоих процессов вы должны удалить канал, точно так же, как вы удаляете обычный файл:

rm fifo

Ответ 4

#!/bin/bash

fifo=$(/bin/mktemp -u)
/usr/bin/mkfifo $fifo

# register resources cleanup trap
trap "/bin/unlink $fifo" INT TERM EXIT

# start a background shell redirecting its output to the pipe
(for ((i=0; i < 5; ++i)); do echo "pam pam, i = $i"; sleep 1; done ) 1> $fifo&

# read the output of the background shell from the pipe
while read line 0< $fifo; do
  echo "param $line"
done

# wait for child process to terminate
wait

Ответ 5

Большинство оболочек делают это трудно, по уважительной причине - очень легко заставить ваши программы заторможены, где каждый ждет ввода от другого. Не могли бы вы рассказать нам больше о том, какую информацию вы пытаетесь пройти? Если вы просто пытаетесь создать RPC-подобную систему, вы, вероятно, должны использовать библиотеку, предназначенную для этого.