Bash
子殼和子殼是一樣的嗎
有這兩個名稱:subshell和child-shell。
是的,子程序將由以下任何一個啟動:
sh -c 'echo "Hello"' ( echo "hello" ) echo "$(echo "hello") echo "hello" | cat
都是等價的並共享相同的名稱嗎?都共享相同的屬性嗎?
POSIX有這個定義:
一個shell執行環境包括……
但是上面連結的最後一段有這個:
子shell 環境應創建為shell 環境的副本,但未被忽略的信號陷阱應設置為預設操作。
特別是:
命令替換、用括號分組的命令和非同步列表應在子 shell 環境中執行。此外,多命令管道的每個命令都處於子shell環境中;……
不包括在那裡,那
sh -c 'echo "Hello"'
也應該稱為子外殼嗎?
子外殼複製現有外殼。它具有相同的變數¹、相同的功能、相同的選項等。在底層,使用
fork
系統呼叫² 創建了一個子shell;子程序繼續執行對它的期望,而父程序等待(例如,$(…)
)或繼續其生命(例如,… &
)或以其他方式執行對它的期望(例如,… | …
)。
sh -c …
不創建子外殼。它啟動另一個程序。該程序恰好是一個外殼,但這只是一個巧合。該程序甚至可能是一個不同的 shell(例如,如果您sh -c …
從 bash 執行,並且sh
是 dash),即,一個完全不同的程序,恰好在其行為上有顯著相似之處。在後台,啟動外部命令(sh
或任何其他命令)呼叫fork
系統呼叫,然後execve
呼叫系統呼叫以將子程序中的 shell 程序替換sh
為另一個程序(此處)。¹包括
$$
但不包括一些特定於 shell 的變數,例如 bash 和 mksh’sBASHPID
。²至少,這是傳統和通常的實現方式。如果 Shell 可以模仿其他行為,那麼它們可以優化分叉。請參閱“子shell”和“子程序”之間的確切區別是什麼?