Bash
在 Bash 中呼叫 subshel l 的規則?
我似乎誤解了創建子外殼的 Bash 規則。我認為括號總是創建一個子shell,它作為自己的程序執行。
然而,情況似乎並非如此。在程式碼片段 A(如下)中,第二個
sleep
命令不在單獨的 shell 中執行(由pstree
另一個終端確定)。但是,在程式碼片段 B 中,第二個sleep
命令確實在單獨的 shell 中執行。片段之間的唯一區別是第二個片段在括號內有兩個命令。有人可以解釋一下創建子shell的規則嗎?
程式碼片段 A:
sleep 5 ( sleep 5 )
程式碼片段 B:
sleep 5 ( x=1 sleep 5 )
括號總是開始一個子shell。發生的事情是 bash 檢測到這
sleep 5
是該子外殼執行的最後一個命令,因此它呼叫exec
而不是fork
+exec
。該sleep
命令替換同一程序中的子shell。換句話說,基本情況是:
( … )
創建一個子外殼。原始程序呼叫fork
和wait
。在子程序中,這是一個子shell:
sleep
是需要子程序的子程序的外部命令。子shell 呼叫fork
和wait
。在子子流程中:
- 子子程序執行外部命令 →
exec
。- 最終命令終止 →
exit
。
wait
在子shell中完成。
wait
在原始過程中完成。優化是:
( … )
創建一個子外殼。原始程序呼叫fork
和wait
。在子程序中,這是一個子shell,直到它呼叫exec
:
sleep
是一個外部命令,它是這個過程需要做的最後一件事。子程序執行外部命令 →
exec
。最終命令終止 →
exit
。
wait
在原始過程中完成。當您在呼叫後添加其他內容時
sleep
,需要保留子shell,因此無法進行此優化。當您在呼叫之前添加其他內容時
sleep
,可以進行優化(並且 ksh 會這樣做),但 bash 不會這樣做(這種優化非常保守)。