在 Linux 上使用命名管道分割输出并重新连接

在 Linux 上使用命名管道分割输出并重新连接

我的问题与https://serverfault.com/questions/171095/how-do-i-join-two-named-pipes-into-single-input-stream-in-linux但设置稍微复杂一些。

我有三个程序,cmd1cmd2cmd3

cmd1不接受输入并写入标准输出

cmd2读取 stdin 或给定文件并写入 stdout

cmd3读取两个文件

这些程序的数据流如下:cmd2使用 生成的数据cmd1,并使用和cmd3生成的数据:cmd1cmd2

cmd1 ---+-----> cmd2 --->
        |                  cmd3
        +---------------> 

如何使用 >()、管道和单个命令行来实现此数据流tee

我最好的猜测是cmd1 | tee >(cmd2) > >(cmd3)

答案1

mkfifo thepipe
cmd3 <( cmd1 | tee thepipe ) <( cmd2 thepipe )

这使用命名管道thepipe来在tee和之间传输数据cmd2

使用你的图表:

cmd1 ---(tee)---(thepipe)--- cmd2 --->
          |                            cmd3
          +-------------------------->

示例为

  • cmd1= echo 'hello world',将字符串写入标准输出。
  • cmd2= rev,反转每行上的字符顺序,读取文件或从标准输入中读取。
  • cmd3= paste,从两个文件(在本例中)获取输入并生成两列。
mkfifo thepipe
paste <( echo 'hello world' | tee thepipe ) <( rev thepipe )

结果:

hello world     dlrow olleh

同样的事情,但是将命名管道放在图中的另一个分支上:

cmd1 ---(tee)--------------- cmd2 --->
          |                            cmd3
          +-----(thepipe)------------>
cmd3 thepipe <( cmd1 | tee thepipe | cmd2 )

使用我们的示例命令:

paste thepipe <( echo 'hello world' | tee thepipe | rev )

这会产生与上面相同的输出。

显然还有其他可能性,例如

cmd1 | tee >( cmd2 >thepipe ) | cmd3 /dev/stdin thepipe

但我认为除非您乐意将中间结果写入临时文件并将其分解为两组命令,否则您无法摆脱使用命名管道的困扰。

相关内容