Bashのマニュアルによると:
コマンド置換、括弧でグループ化されたコマンド、および非同期コマンドは、シェル環境の複製であるサブシェル環境で呼び出されます。ただし、シェルによってキャッチされたトラップは、シェルが親から継承した値にリセットされます。呼び出し。
この例では、b
は環境変数ではないため、b
コマンド置換によって作成されたサブシェルには存在しません。では、なぜc
なのか b
の値を割り当てました コマンド置換によって? $b
のパラメータ展開が発生したためですか echo 1
を実行するサブシェルを作成する前にシェルプロセスで ?
$ b=1
$ c=$(echo $b)
$ echo $c
1
承認された回答:
いいえ、サブシェルが最初に作成されました。
シェル実行環境には、変数の割り当てと環境変数によって設定されたシェルパラメータが含まれています。サブシェル環境は、シェル環境を複製することによって作成されたため、現在のシェル環境のすべての変数が含まれています。
例を参照してください:
$ b=1
$ c=$(b=2; echo "$b")
$ echo "$c"
2
出力は2
です 1
の代わりに 。
コマンド置換によって作成されたサブシェル環境は、シェル実行可能ファイルを呼び出して作成されたシェル環境とは異なります。
シェルを次のように呼び出す場合:
$ bash -c :
現在のシェルはexecve()を使用して、次のような新しいシェルプロセスを作成しました。
execve("/bin/bash", ["bash", "-c", ":"], [/* 64 vars */]) = 0
execve
に渡された最後の引数 すべての環境変数が含まれています。
そのため、変数をエクスポートして環境変数にプッシュする必要があります。環境変数は、後で実行されるコマンドに含まれます。
$ a=; export a
$ strace -e execve bash -c :
execve("/bin/bash", ["bash", "-c", ":"], [/* 65 vars */]) = 0
+++ exited with 0 +++
環境変数が64から65に変更されていることに注意してください。また、エクスポートされない変数は新しいシェル環境に渡されません:
$ a=; b=; export a
$ strace -e execve bash -c :
execve("/bin/bash", ["bash", "-c", ":"], [/* 65 vars */]) = 0
+++ exited with 0 +++
環境変数がまだ65であることに注意してください。
コマンド置換では、シェルはfork()を使用して、変数セットと環境変数の両方を含む現在のシェル環境をコピーした新しいシェルプロセスを作成しました。