Bash

子殼和子殼是一樣的嗎

  • September 24, 2021

有這兩個名稱:subshel​​lchild-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’s BASHPID

²至少,這是傳統和通常的實現方式。如果 Shell 可以模仿其他行為,那麼它們可以優化分叉。請參閱“子shell”和“子程序”之間的確切區別是什麼?

相關手冊頁:fork(2)execve(2)

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