回答:
$(…)
定義上、サブシェルです。これはシェルのランタイム状態¹のコピーであり、サブシェルで行われた状態への変更は親に影響を与えません。サブシェルは通常、新しいプロセスをフォークすることで実装されます(ただし、一部のシェルは場合によってはこれを最適化できます)。
変数値を取得できるサブシェルではありません。変数の変更が親に影響を与えた場合、それはサブシェルではありません。これは、親が取得できる出力を持つサブシェルです。によって作成されたサブシェルの$(…)
標準出力はパイプに設定され、親はそのパイプから読み取り、出力を収集します。
サブシェルを作成するいくつかの他の構造があります。これはbashの完全なリストだと思います。
( … )
何もしませんが、サブシェル、それが終了するのを待ちます)を作成します。{ … }
どのグループが純粋に構文上の目的でコマンドをグループ化し、サブシェルを作成しないかと対照的です。… &
サブシェルを作成し、サブシェルが終了するのを待ちません。… | …
2つのサブシェルを作成します。1つは左側、もう1つは右側にあり、両方が終了するのを待ちます。シェルはパイプを作成し、左側の標準出力をパイプの書き込み側に接続し、右側の標準入力を読み取り側に接続します。一部のシェル(ksh88、ksh93、zsh、bash lastpipe
オプションが有効に設定されている)では、右側が元のシェルで実行されるため、パイプライン構造は1つのサブシェルのみを作成します。$(…)
も綴ります`…`
)パイプに設定された標準出力でサブシェルを作成し、親で出力を収集し、その出力から末尾の改行を除いて展開します。(そして、出力はさらに分割とグロビングの対象になるかもしれませんが、それは別の話です。)<(…)
標準出力がパイプに設定されたサブシェルを作成し、パイプの名前に展開します。親(または他のプロセス)は、パイプを開いてサブシェルと通信できます。>(…)
同じことをしますが、標準入力にパイプを使用します。coproc …
サブシェルを作成し、終了するまで待機しません。サブシェルの標準入力および出力はそれぞれパイプに設定され、親は各パイプのもう一方の端に接続されます。${...}
回答に含めてもらえますか?
command | { read line; … }
(シェルによって異なりline
ますが、パイプラインの後でまだ利用できる場合とできない場合があります)。出力を生成するコマンドは入力を読み取るシェルとは独立して実行する必要があるため、すべての方法にサブシェルが含まれます。コマンドが純粋にシェルの内部にある場合(シェル構成と組み込みのみ、外部コマンドはない)、シェルはサブプロセスを作成しないかもしれませんが、それは単なる最適化であり、サブシェルを作成します。
bashバージョン4.4のbash(1)のマニュアルページから、「EXPANSION」セクション、「Command Substitution」サブセクション:
Bashは、
command
サブシェル環境で実行することにより展開を実行します[...]
bash
マンページにはサブシェルが記載されていませんBash performs the expansion by executing command and replacing the command substitution with the standard output of the command, with any trailing newlines deleted.
。これは意図的な省略であったのでしょうか。