子 shell 與子 shell 相同嗎

子 shell 與子 shell 相同嗎

有這兩個名字:a子外殼和一個子殼

是的,子進程將透過以下任一方式啟動:

sh -c 'echo "Hello"'
( echo "hello" )
echo "$(echo "hello")
echo "hello" | cat

都是等價的並且具有相同的名稱嗎?所有人都具有相同的屬性嗎?


POSIX有這個定義:

shell執行環境包括......

但上面連結的最後一段是這樣的:

子 shell 環境應建立為 shell 環境的副本,但未被忽略的訊號陷阱應設定為預設操作。

特別是:

命令替換、用括號分組的命令以及非同步列表應在子 shell 環境中執行。此外,多命令管道中的每個命令都位於子shell環境中; ....

sh -c 'echo "Hello"'包含在那裡,那也應該稱為子shell嗎?

答案1

一個子shell重複項現有的外殼。它具有相同的變數、相同的函數、相同的選項等。fork系統調用²;子程序繼續執行預期的操作,而父程序則等待(例如,$(…))或繼續其生命(例如,… &)或以其他方式執行預期的操作(例如,… | …)。

sh -c …不建立子shell。它啟動另一個程式。程式恰好是一個 shell,但這只是一個巧合。該程式甚至可能是不同的 shell(例如,如果您sh -c …從 bash 運行,並且sh是 dash),即一個完全不同的程序,只是其行為恰好有顯著的相似之處。在幕後,啟動外部命令(sh或任何其他命令)會調用fork系統調用,然後execve系統調用代替子進程中的 shell 程式由另一個程式執行(此處sh)。

¹包括$$,但不包括一些特定於 shell 的變量,例如 bash 和 mksh 的BASHPID
²至少,這是傳統且通常的實作方式。如果 shell 能夠模仿行為,那麼它們就可以最佳化分叉。看「子shell」和「子進程」之間的確切差異是什麼?

相關手冊頁:叉子(2),執行(2)

答案2

子 shell 環境不需要存在於單獨的進程中,它只需要複製目前的執行環境。這ksh93是透過virtual sub-shell不調用fork().這使得 ksh93 在像 一樣的古老平台上非常快Win-DOS,而Win-DOS分叉時卻非常慢。

sh -c cmd另一方面,使用預設 shell 建立一個新進程,該進程不需要與目前的互動式 shell 相同。

即使sh當前 shell 相同,也不會複製執行環境,因此不會創建sub-shell.

相關內容