回答:
コマンドを評価するさまざまなステップが発生する順序の問題です。
A=10 echo $A
最初に、コマンドを3つの単語A=10
からなる単純なコマンドに解析します、echo
そして$A
。次に、各単語は変数置換、つまり$A
値への変換などの変数展開の変換を受けます(目に見えないステップは省略しています)。
A
がfoo
最初に値を持っている場合、展開手順の結果は、3つの単語がまだある単純なコマンドA=10
にecho
なります:、およびfoo
。(シェルはこの時点で、最初に引用符で囲まれた文字を記憶します。この場合はどれもありません。)次のステップはコマンドの実行です。以来、A=10
等号、続いて有効な変数名で始まり、それが割り当てとして扱われます。変数A
は10
、コマンドの実行中にシェルと環境の両方で設定されます。(通常、シェル変数としてだけでなく、環境内で使用するように記述export A
する必要がありA
ます。これは例外です。)次の単語は割り当てではないため、コマンド名(組み込みコマンド)として扱われます。のecho
コマンドは変数に依存しないためA=10 echo $A
、と同じ効果がありecho $A
ます。
コマンドの実行中のみ変数を設定したいが、コマンドの実行中に割り当てを考慮する場合は、サブシェルを使用できます。括弧で示されたサブシェルは、すべての状態変更(変数の割り当て、現在のディレクトリ、関数定義など)をサブシェルに対してローカルにします。
(A=10; echo $A)
ことを確認してくださいexport A=10
あなたはそれが外部プログラムによって見られるように、環境に変数をエクスポートする場合。
A=10; (echo $A)
出力します10
がA
、スクリプトの残りの部分も設定します。
A=10 eval 'echo $A'
。$A
行全体が評価されるまで、単一引用符は解釈されなくなります...その時点までにA = 10になります。この答えは受け入れられたものよりも正しいと思います。
$A
と割り当てが発生する順序だけA
です。たとえば、A=5; A=6 let 'a=A'; echo $a
戻り値6
は5
ありませんlet
。組み込みコマンドなので、サブシェルを開始するとは思いません。
A=10 echo $A
でしょうではないしA=10
、その後の任意のコマンドのために、彼らは別の行にあっても(割り当てが時に明確にして、すでに評価されます)。それはについてです、順序についてではありませんスコープ
あなたは使用する場合LANG=C gcc ...
、何が起こるかのためにシェルが設定されることLANGあるgcc
環境の唯一の、そしてないため、現在の環境自体は、(注を参照)。したがって、gcc
終了後LANG
、以前の値に戻ります(または設定解除されます)。
さらに、使用するA=10 echo $A
ときは、エコーではなく$ Aを置換するシェルであり、この代入(「展開」と呼ばれる)はステートメントが評価される前(割り当てを含む)に発生するため、期待どおりに動作するにはA
値が既に設定されている必要がありますその文の前の現在の環境で。
そのためA=10 echo $A
、期待どおりに機能しません。A=10
エコーが設定されますが、エコーは内部的に環境変数の値を無視しますA
。そして、$A
の値のセットに置き換えられる現在のシェル(noneです)、そして次いでエコーに引数として渡されます。
したがって、あなたの仮定は正しいです:VAR=value command
動作しますが、これはcommand
内部でVARを使用する場合にのみ関連します。そうでない場合、あなたはまだ渡すことができますvalue
よう、引数にcommand
、しかし、引数が置き換えられている現在のシェルので、それらは使用前に設定する必要があります。VAR=value; command "$VAR"
実行可能スクリプトの作成方法がわかっている場合は、テストとしてこれを試すことができます。
#!/bin/sh
echo "1st argument is $1"
echo "A is $A"
名前を付けて保存してtestscript
みてください:
$ A=5; A=10 testscript "$A"; echo "$A"
1st argument is 5
A is 10
5
最後になりましたが、違いを知ることの価値がシェルと環境変数とプログラムの引数を。
以下に参考資料を示します。
。
(*)注:技術的にはシェルがない、あまりにも現在の環境に設定され、そしてなぜここにある:いくつかのコマンドのようなecho
、read
とtest
しているシェル組み込みコマンド、そのように彼らは、子プロセスを生成しません。現在の環境で実行されます。ただし、シェルは、コマンドが実行されるまで割り当てを継続するだけなので、すべての実際的な目的で効果は同じです。割り当てはその単一のコマンドによってのみ表示されます。
$A
割り当てが行われる前に評価されます。あなたの説明は、その動作が変数の値に依存する通常の組み込みユーティリティの場合にのみ失敗すると思います:組み込みは割り当てられた値を見ます。一般的な例はでIFS=: read one two three rest
、コロンで区切られたフィールドを読み取ります:read
組み込みはの値を見ますIFS
。
echo
、の値10
を見るでしょうA
。
pid
)が他の「通常の」コマンドのように割り当てを見ることができません。ただし、割り当てスコープを制限するためにコマンドが実行されると、設定が解除されます。これは正しいですか、それに応じて答えを修正します。PS:技術的なことはさておき、答えは評価の順序ではなくスコープの側面に重点を置くべきだと思います。そうでなければ、A=10 test; echo $A
10
A=10 (echo $A)
てもらうことができます10
か?