如何複製流並以流方式處理兩個部分?

如何複製流並以流方式處理兩個部分?

有時我想在管道中插入一些東西以用於報告或其他一些次要用途。它可能像 一樣簡單wc -l,或更複雜,甚至awk是 python 腳本。運行這樣的管道會很好:

zcat my_data_file.gz \
| wc -l > /tmp/linecount
| process_data.py

問題是大多數實用程式不會將資料正確輸出到標準輸出。tee可以將資料寫入臨時文件,但是我必須等到一切完成:

zcat my_data_file.gz \
| tee /tmp/f \
| process_data.py && \
wc -l /tmp/f > /tmp/linecount && rm /tmp/f

這不是最佳的:它可能是一個運行時間非常長的管道;我可能希望wc更快看到類似物的中間結果;我可能不想將所有資料儲存在臨時檔案中。

答案1

您可以使用tee並處理替換>(...)

zcat my_data_file.gz |

# Count number of lines in stream
tee >(wc -l > /tmp/linecount) |

# Further processing
process_data.py

請注意,管道可用於行延續,並且註釋可以散佈在命令之間,這是建立複雜管道時的一個很好的功能。

答案2

它並不完全有效,但你可以透過以下方式實現這一點命名管道,您可以使用它來創建mkififo(1)

對於問題中的例子:

mkfifo /tmp/f

wc -l /tmp/f > /tmp/linecount &

zcat my_data_file.gz \
| tee /tmp/f \
| process_data.py &

wait

rm /tmp/f

注意&附加在wc和 管道上的;這表示 shell 會將任務推送到背景。然後,呼叫將wait等待所有後台任務結束。這兩個過程將大約在同一時間完成。

請注意,如果您的某個進程速度明顯較慢,則可能會顯著減慢整個進程的速度,因為tee可能會阻塞其標準輸出管道或正在寫入的命名管道。編輯:此外,它現在有更多的故障模式,因為如果輔助進程失敗,tee 將因管道損壞而退出。

相關內容