
この2つの名前があります:サブシェルそして子シェル。
はい、子プロセスは次のいずれかによって開始されます。
sh -c 'echo "Hello"'
( echo "hello" )
echo "$(echo "hello")
echo "hello" | cat
すべて同等で同じ名前を共有していますか? すべて同じプロパティを共有していますか?
POSIXこの定義がある:
シェル実行環境は...で構成されます。
しかし、上記リンクの最後の段落には次の記述があります:
サブシェル環境は、無視されないシグナル トラップがデフォルトのアクションに設定される点を除き、シェル環境の複製として作成されます。
そして特に:
コマンド置換、括弧でグループ化されたコマンド、および非同期リストは、サブシェル環境で実行されます。さらに、複数コマンドのパイプラインの各コマンドはサブシェル環境にあります。
はsh -c 'echo "Hello"'
そこに含まれていませんが、これもサブシェルと呼ぶべきでしょうか?
答え1
サブシェル重複既存のシェルと同じです。同じ変数¹、同じ機能、同じオプションなどを持ちます。内部的には、サブシェルが作成され、fork
システム コール²。子プロセスは、親プロセスが待機する (例: $(…)
) か、処理を続行する (例: )… &
か、そうでなければ期待される処理を実行する (例: … | …
) 間、期待される処理を続行します。
sh -c …
サブシェルは作成されません。別のプログラムを起動します。そのプログラムはたまたまシェルですが、それは単なる偶然です。プログラムは別のシェルである可能性もあります(たとえば、sh -c …
bashから実行し、sh
dashである場合)、つまり、まったく異なるプログラムですが、動作にかなりの類似点があります。内部的には、外部コマンド(sh
またはその他のコマンド)を起動すると、fork
システムコールが呼び出され、次にexecve
システムコール交換するサブプロセス内のシェル プログラムを別のプログラム (ここではsh
) によって実行します。
¹を含みますが$$
、bash や mksh の などのシェル固有の変数は除きますBASHPID
。²
少なくとも、これは伝統的で通常の実装です。シェルは、他の動作を模倣できる場合は、フォークを最適化して取り除くことができます。「サブシェル」と「子プロセス」の正確な違いは何ですか?
答え2
サブシェル環境は別のプロセスに存在する必要はなく、現在の実行環境を複製するだけで済みます。 では、を呼び出さないメカニズムksh93
によってこれが行われます。 これにより、 のような古いプラットフォームでは ksh93 が非常に高速になりますが、 ではフォークにより非常に低速になります。virtual sub-shell
fork()
Win-DOS
Win-DOS
sh -c cmd
一方、デフォルトのシェルを使用して新しいプロセスを作成します。このシェルは、現在の対話型シェルと同じである必要はありません。
と現在のシェルが同一の場合でもsh
、実行環境は複製されないため、 は作成されませんsub-shell
。