この2つの名前があります:サブシェル および子シェル 。
はい、子プロセスは次のいずれかによって開始されます:
sh -c 'echo "Hello"'
( echo "hello" )
echo "$(echo "hello")
echo "hello" | cat
すべて同等で、同じ名前を共有していますか?すべて同じプロパティを共有していますか?
POSIXには次の定義があります:
シェル実行環境は…で構成されています。
しかし、上記のリンクの最後の段落にはこれがあります:
サブシェル環境は、無視されないシグナルトラップがデフォルトのアクションに設定されることを除いて、シェル環境の複製として作成されます。
そして特別に:
コマンド置換、括弧でグループ化されたコマンド、および非同期リストは、サブシェル環境で実行される必要があります。さらに、マルチコマンドパイプラインの各コマンドはサブシェル環境にあります。 …。
sh -c 'echo "Hello"'
そこには含まれていませんが、それもサブシェルと呼ばれるべきですか?
承認された回答:
サブシェルは複製 既存のシェル。同じ変数¹、同じ関数、同じオプションなどがあります。内部では、fork
を使用してサブシェルが作成されます。 システムコール²;子プロセスは、親が待機している間、期待されることを実行し続けます(例:$(…)
)またはその寿命を継続します(例:… &
)またはその他の方法で期待されることを実行します(例:… | …
。
sh -c …
サブシェルを作成しません。別のプログラムを起動します。そのプログラムはたまたまシェルですが、それは単なる偶然です。プログラムは別のシェルである場合もあります(たとえば、sh -c …
を実行した場合 bashから、およびsh
ダッシュ)、つまり、まったく異なるプログラムであり、その動作に大きな類似点があります。内部で、外部コマンド(sh
またはその他)fork
を呼び出します システムコールしてからexecve
置換へのシステムコール 別のプログラムによるサブプロセスのシェルプログラム(ここではsh
。
¹$$
を含む 、ただし、bashやmkshのBASHPID
などの一部のシェル固有の変数は除外されます 。
²少なくとも、これは従来の通常の実装です。シェルは、他の動作を模倣できる場合は、フォークを最適化できます。
関連するマニュアルページ:fork(2)、execve(2)。