Linux

在 Linux 上使用命名管道拆分輸出並再次重新加入

  • June 22, 2018

我的問題與https://serverfault.com/questions/171095/how-do-i-join-two-named-pipes-into-single-input-stream-in-linux有關,但設置稍微複雜一些。

我有三個程序cmd1cmd2cmd3;

cmd1不接受任何輸入並寫入標準輸出

cmd2讀取標準輸入或給定文件並寫入標準輸出

cmd3讀取兩個文件

這些程序的數據流如下:cmd2使用由 生成的數據cmd1,並使用由 和生成cmd3的數據:cmd1``cmd2

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

如何使用 >()、管道和 使用單個命令行來實現此數據流tee

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

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

但我認為除非您樂於將中間結果寫入臨時文件並將其分解為兩組命令,否則您無法避免使用命名管道。

引用自:https://unix.stackexchange.com/questions/451362