回答:
これは、実際にコマンドを実行する前にシェルがコマンドラインの変数を展開し、その時点で変数が存在しないためです。使用する場合
TEST=foo; echo $TEST
それが動作します。
export
変数は、その後実行されるコマンドの環境に表示されます(bashでの動作については、を参照してくださいhelp export
)。1つのコマンドの環境に変数を表示するだけでよい場合は、試したものを使用します。
TEST=foo your-application
$TEST
コマンドラインが実行される前にシェルが展開します。一度echo
実行されている(また、それは注意してecho
、通常は組み込みコマンドシェルに変換しないようになり/bin/echo
、それがその環境での変数のセットを見ています)。ただし、その環境から変数の内容を出力するecho $TEST
ように指示echo
しませんTEST
。echo
現在呼び出されている変数にあるものを引数として実行するようにシェルに指示しますTEST
。これらは2つの非常に異なるものです。
var=value sh -c 'echo "$var"'
ですか?
sh -c
)子シェルによって実行されます。
環境変数ではなく、シェル変数のスコープを制限したいのではないでしょうか。環境変数は、それらがされたときにコマンドに渡された文字列のリストです実行します。
に
var=value echo whatever
var=value
エコーが受信する環境に文字列を渡します。ただし、echo
その環境リストでは何もせず、とにかくほとんどのシェルでecho
組み込まれているため、実行されません。
あなたが書いていた場合
var=value sh -c 'echo "$var"'
それは別の問題だったでしょう。ここではvar=value
、sh
コマンドに渡していますが、sh
たまたまその環境を使用しています。シェルは、環境から受け取る各変数をシェル変数に変換するため、var
環境変数がsh
受け取る変数は変数に変換され、$var
そのecho
コマンドラインで展開すると、になりecho value
ます。環境はデフォルトで継承されるため、環境内でecho
も受信var=value
します(または実行された場合は受信します)がecho
、環境については気にしません。
さて、私が疑うように、シェル変数のスコープを制限したい場合、いくつかの可能なアプローチがあります。
移植可能(BourneおよびPOSIX):
(var=value; echo "1: $var"); echo "2: $var"
上記の(...)はサブシェル(ほとんどのシェルの新しいシェルプロセス)を開始するため、そこで宣言された変数はそのサブシェルにのみ影響するため、上記のコードは「1:value」を出力するはずですおよび「2:」または「2:whatever-var-was-set-to-before」。
ほとんどのBourneライクシェルでは、関数と「ローカル」ビルトインを使用できます。
f() {
local var
var=value
echo "1: $var"
}
f
echo "2: $var"
zshでは、インライン関数を使用できます。
(){ local var=value; echo "1: $var"; }; echo "2: $var"
または:
function { local var=value; echo "1: $var"; }; echo "2: $var"
bashとzsh(ash、pdksh、AT&T kshではない)を使用すると、このトリックも機能します。
var=value eval 'echo "1: $var"'; echo "2: $var"
さらにいくつかのシェルで動作バリアント(dash
、mksh
、yash
)ではなくzsh
(でない限りsh
/ ksh
エミュレーション):
var=value command eval 'echo "1: $var"'; echo "2: $var"
(POSIXシェルのcommand
特別な組み込み(ここeval
)の前で使用すると、その特殊性が削除されます(ここで、変数の割り当ては、それらから返された後も有効です)
あなたはそれを正しくやっていますが、bash構文は誤解されやすいです:env var を取得してから印刷するecho $TEST
原因と考えることができますが、そうではありません。だから与えられたecho
TEST
export TEST=123
それから
TEST=456 echo $TEST
次のシーケンスが含まれます。
シェルはコマンドライン全体を解析し、すべての変数置換を実行するため、コマンドラインは
TEST=456 echo 123
コマンドの前に設定された一時変数を作成し、現在の値を保存TEST
して456で上書きします。コマンドラインは今
echo 123
残りのコマンドを実行します。この場合、123をstdoutに出力します(そのため、残っているシェルコマンドはの一時値を使用しませんでしたTEST
)。
の値を復元します TEST
代わりにprintenvを使用してください。変数の置換が含まれていないためです。
>> export TEST=123
>> printenv TEST
123
>> TEST=456 printenv TEST
456
>> printenv TEST && TEST=456 printenv TEST && TEST=789 printenv TEST && printenv TEST
123
456
789
123
>>
printenv
テスト/概念実証に役立つことがわかった(スクリプトではなく、スクリプトのように動作するecho
)
以下を使用して、これを機能させることができます。
TEST=foo && echo $TEST
TEST=foo
は別のステートメントとして実行されています-のコンテキストで設定されるだけではありませんecho
。