构建带循环的管道拓扑,共享接收器

constructing pipe topology w/ loops, shared sink

我浏览了一些 bash i/o 教程,但其中大部分都涉及重定向流 to/from 文件。

我想制作自己的管道(命名或未命名),使用文件描述符并使用它们连接多个程序或脚本,以便它们相互通信。

例如,提供一个拓扑示例,这应该能够构建:

因此,构建的拓扑应该如下所示:

prog1 <-----> prog2
     \       /
      \     /
       \   /
        \ /
         V
       prog3

像这样的拓扑有点棘手,但如果您不需要同步写入,这是可能的。


我强烈建议避免在这种做法上挂起任何关键任务。但是,在 /dev/fd 可用的任何操作系统上,都可以执行类似于以下操作的操作:

mkfifo prog3_in  # create a named pipe
exec 5<>prog3_in # open read/write: this handle will be inherited by subprocesses, allowing
                 # the two tees to both write to the same stream

mkfifo prog1_out
mkfifo prog2_out

# at minimum the first program must be opened in the background, since opening prog1_out
# for write will hang until a reader is available
prog1 5>&- <prog2_out | tee /dev/fd/5 >prog1_out &
prog2 5>&- <prog1_out | tee /dev/fd/5 >prog2_out &
prog3 <&5 5>&- &

exec 5>&-  # parent shell: close FD 5
wait       # ...and wait for children to exit.

tee,或者在单次写入导致多个 reads 的任何情况下,都需要一些等价物。 (tee 本身从 stdin 读取,然后写入每个指定的输出)。


就是说,如果您的程序是按照这种拓扑结构构建的,只需将它们编写为将命名管道名称作为参数,并将 shell 排除在外:

prog1 --prog1-pipe=pipe1 --prog2-pipe=pipe2 --prog3-pipe=pipe3.1
prog2 --prog1-pipe=pipe1 --prog2-pipe=pipe2 --prog3-pipe=pipe3.2

# just make prog3 responsible for reading from *both* output pipes
prog3 pipe3.1 pipe3.2