這取決於你的shell和你調用的程序。
從理論上講,你可以使用具有N個非根節點的任何可變參數樹的可能性,其中一些組合爆炸:
shell shell shell
/ / \ / \
grep x ls grep y ls grep y
/\ \ \ / \
ls grep y grep x grep z grep x grep z
\
grep z
一個POSIX標準的shell,雖然是required to wait for the last stage to finish與繼續之前下一個命令。由於進程只能在子進程中使用wait,這意味着最後一個階段必須是主shell的子進程。 POSIX補貼額外等待所有階段,這是bash
和大多數其他shell所做的(嘗試sleep 5 | true
)。
這意味着bash
將所有進程作爲自己的子進程啓動,您可以使用例如strace -f -e clone bash -c 'sleep 5 | sleep 5 | sleep 5'
或sleep 5 | sleep 5 | sleep 5 & pstree -p $$
,如果您不想在bash源代碼中的execute_cmd.c
中研究execute_pipeline
。
這還有一個額外的好處,就是允許bash的PIPESTATUS數組和pipefail選項作用於管道中所有階段的狀態,如果所有階段都不是直接的子進程,那麼這是不可能的。
另一個考慮是程序很少處理他們沒有想到的孩子。充其量,你將得到一個殭屍進程,最壞的情況是它會干擾進程的正確性。這意味着ls
不應該是grep
的直接子代,反之亦然。但是,您可以通過double fork將其設置爲孫子,以便init
可以對此負責。
所以,是的,你可以使用任何你想要的配置,但在實踐中(如在bash
,dash
,ash
和zsh
),它會趨於平坦。
哇。非常感謝,這正是我正在尋找的。我需要一段時間來處理你給我的所有信息,並嘗試理解事情。謝謝 :) – skynet