2011-02-24 259 views
11

我想了解shell如何執行管道命令?例如貓|更多。我知道,執行一個正常的命令外殼做一個分叉,執行它,然後子返回。但是shell如何在內部處理管道命令的執行?shell如何執行管道命令?

回答

12

考慮到例如cat | grep,shell首先分叉自己啓動cat,然後再次分叉以開始grep

在兩個新創建的進程中調用其中一個exec*函數來啓動兩個程序之前,棘手的部分是設置管道並重定向描述符。系統調用pipe(2)在分支之前用於返回一對描述符,這兩個描述符都是子繼承 - 讀取結束和寫入結束。

讀取結束將在第一個進程(cat)中關閉,標準輸出將使用系統調用dup2(2)重定向到寫入結束。類似地,第二個進程(grep)中的寫入結束將被關閉,stdin將被重新定向到使用dup2(2)的讀取結束。

這樣,兩個程序都不知道管道,因爲他們只是使用標準輸入/輸出。

+0

嗨Blagovest,我有點困惑。 grep是貓的孩子還是shell的孩子?貓如何知道它必須爲grep分叉? – cppdev 2011-02-24 07:36:48

+0

你是對的,特別是bash不會創造第二個過程作爲第一個過程的孩子,但是這個原理依然成立,而且這兩個過程仍然是殼的孩子。 – 2011-02-24 07:41:02

4

它使用pipe系統調用設置管道,分叉兩個進程而不是一個進程,並將管道的一端連接到第一個進程的stdout,另一端連接到第二個進程的stdin。

+0

你能解釋一下如何將一個進程的stdout與另一個進程的stdin一起加入嗎? – cppdev 2011-02-24 07:29:39

+1

@cppdev:使用'dup2',但你已經從Blagovest的答案中找到了答案。 @Downvoter:這個答案有什麼問題,除了它太短? – 2011-02-24 08:52:18