Bash

在 Bash 中呼叫 subshel l 的規則?

  • April 3, 2018

我似乎誤解了創建子外殼的 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。

換句話說,基本情況是:

  1. ( … )創建一個子外殼。原始程序呼叫forkwait。在子程序中,這是一個子shell:

  2. sleep是需要子程序的子程序的外部命令。子shell 呼叫forkwait。在子子流程中:

    1. 子子程序執行外部命令 → exec
    2. 最終命令終止 → exit
  3. wait在子shell中完成。

  4. wait在原始過程中完成。

優化是:

  1. ( … )創建一個子外殼。原始程序呼叫forkwait。在子程序中,這是一個子shell,直到它呼叫exec

  2. sleep是一個外部命令,它是這個過程需要做的最後一件事。

  3. 子程序執行外部命令 → exec

  4. 最終命令終止 → exit

  5. wait在原始過程中完成。

當您在呼叫後添加其他內容時sleep,需要保留子shell,因此無法進行此優化。

當您在呼叫之前添加其他內容時sleep,可以進行優化(並且 ksh 會這樣做),但 bash 不會這樣做(這種優化非常保守)。

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