問題、再訪
率直に言って、マニュアルはこの点で混乱しています。GNU bashのマニュアルは言います:
シェルのパラメーターで説明されているように、単純なコマンドまたは関数の環境[組み込みのものは除外されることに注意してください]は、パラメーターの割り当てを前に付けることによって一時的に拡張できます。これらの割り当てステートメントは、そのコマンドが認識する環境にのみ影響します。
文を実際に解析すると、コマンド/関数の環境は変更されますが、親プロセスの環境は変更されないということです。したがって、これは機能します:
$ TESTVAR=bbb env | fgrep TESTVAR
TESTVAR=bbb
envコマンドの環境は、実行前に変更されているためです。ただし、これは機能しません。
$ set -x; TESTVAR=bbb echo aaa $TESTVAR ccc
+ TESTVAR=bbb
+ echo aaa ccc
aaa ccc
これは、シェルによってパラメーターの展開が実行されるためです。
通訳の手順
問題のもう1つの部分は、Bash がインタープリターに対してこれらのステップを定義していることです。
- ファイル(シェルスクリプトを参照)、-c呼び出しオプションの引数として指定された文字列(Bashの呼び出しを参照)、またはユーザーの端末から入力を読み取ります。
- 入力を単語と演算子に分解し、引用で説明されている引用規則に従います。これらのトークンはメタ文字で区切られています。エイリアスの展開は、このステップで実行されます(エイリアスを参照)。
- トークンを単純なコマンドと複合コマンドに解析します(シェルコマンドを参照)。
- さまざまなシェル展開(シェル展開を参照)を実行し、展開されたトークンをファイル名(ファイル名展開を参照)およびコマンドと引数のリストに分割します。
- 必要なリダイレクト(リダイレクトを参照)を実行し、リダイレクト演算子とそのオペランドを引数リストから削除します。
- コマンドを実行します(コマンドの実行を参照)。
- オプションで、コマンドが完了するまで待機し、その終了ステータスを収集します(終了ステータスを参照)。
ここで何が起こっているかというと、ビルトインは独自の実行環境を取得しないため、変更された環境を見ることはありません。さらに、単純なコマンド(例:/ bin / echo)は変更された環境を取得します(これがenvの例が機能した理由です)が、ステップ4で現在の環境でシェルの拡張が行われています。
つまり、「aaa $ TESTVAR ccc」を/ bin / echoに渡していません。(現在の環境で展開されている)補間された文字列を/ bin / echoに渡します。この場合、現在の環境にはTESTVARがないため、コマンドに 'aaa ccc'を渡すだけです。
概要
ドキュメントはもっと明確になるでしょう。スタックオーバーフローがあるのは良いことです。
こちらもご覧ください
http://www.gnu.org/software/bash/manual/bashref.html#Command-Execution-Environment