昨日、bash でコマンド置換を使用すると、不要なサブシェルが生成されることが示唆されました。アドバイスは、このユースケースに固有のものでした:
# Extra subshell spawned
foo=$(command; echo $?)
# No extra subshell
command
foo=$?
私が理解できる限り、これはこのユースケースには正しいようです。ただし、これを確認しようとして簡単に検索すると、混乱し矛盾するアドバイスが大量に出てきます。コマンド置換をすべて使用すると、サブシェルが生成されるという一般的な知恵があるようです。例えば:
コマンド置換は、コマンドの出力に展開されます。これらのコマンドはサブシェルで実行され、それらの stdout データは、置換構文が展開されるものです。(ソース)
掘り続けない限り、これは十分に単純に思えますが、掘り下げ続けると、そうではないという提案への参照を見つけ始めるでしょう。
コマンド置換は必ずしも subshell を呼び出すとは限らず、ほとんどの場合は呼び出されません。それが保証する唯一のものは順不同の評価です: 最初に置換内の式を評価し、次に置換の結果を使用して周囲のステートメントを評価します。(ソース)
これは理にかなっているように思えますが、本当ですか? サブシェル関連の質問に対するこの回答man bash
は、次のことに注意してください。
パイプライン内の各コマンドは、個別のプロセスとして (つまり、サブシェル内で) 実行されます。
これは私を主な質問に導きます。正確には、コマンド置換によって、同じコマンドを分離して実行するために、とにかく生成されなかったサブシェルが生成される原因は何ですか?
次のケースを検討し、余分なサブシェルのオーバーヘッドが発生するケースを説明してください。
# Case #1
command1
var=$(command1)
# Case #2
command1 | command2
var=$(command1 | command2)
# Case #3
command1 | command 2 ; var=$?
var=$(command1 | command2 ; echo $?)
これらの各ペアは、実行するサブシェルの数が同じですか? POSIX と bash の実装に違いはありますか? コマンド置換を使用するとサブシェルが生成され、同じコマンド セットを単独で実行しても生成されない他のケースはありますか?