この2つの名前があります。asubshellとachild-Shellです。
はい、子プロセスは次のいずれかによって開始されます:
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
システムコールreplaceサブプロセス内のシェルプログラムを別のプログラム(ここではsh
)に置き換えます。
¹ $$
を含みますが、bashやmkshのBASHPID
などのシェル固有の変数をいくつか除外します。
² 少なくとも、これは従来の通常の実装です。シェルは、振る舞いを模倣できればフォークを最適化できます。
サブシェル環境は、別のプロセスに存在する必要はありません。現在の実行環境を複製する必要があるだけです。 _ksh93
_では、これはfork()
を呼び出さない_virtual sub-Shell
_メカニズムによって行われます。 _Win-DOS
_はフォークで非常に遅いので、これは_Win-DOS
_のような古いプラットフォームでksh93を非常に高速にします。
反対側の_sh -c cmd
_は、現在の対話型シェルと同じである必要がないデフォルトのシェルで新しいプロセスを作成します。
sh
と現在のシェルが同一であっても、これは実行環境を複製しないため、_sub-Shell
_は作成されません。