Shell

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

  • April 15, 2013

有時我想在管道中插入一些東西以進行報告或其他一些次要用途。它可能很簡單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更快地看到模擬的中間結果;而且我可能不想將所有數據儲存在臨時文件中。

您可以為此使用tee和處理替換>(...)

zcat my_data_file.gz |

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

# Further processing
process_data.py

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

它並不完全有效,但是您可以使用命名管道來實現這一點,您可以使用它來創建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 會將任務推送到後台。呼叫waitthen 等待所有後台任務結束。這兩個過程將在大約同一時間完成。

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

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