走れば
export TEST=foo
echo $TEST
Fooを出力します。
走れば
TEST=foo echo $TEST
ありません。エクスポートやスクリプトを使用せずにこの機能を取得するにはどうすればよいですか?
これは、シェルがコマンドラインで変数を展開するためですbeforeそれは実際にコマンドを実行し、その時点では変数は存在しません。使用する場合
TEST=foo; echo $TEST
それが動作します。
export
は、その後に実行されるコマンドの環境に変数を表示します(これがbashでどのように機能するかについては、help export
を参照してください)。変数が1つのコマンドの環境に表示されるだけでよい場合は、試したものを使用してください。
TEST=foo your-application
環境変数ではなくShell変数でスコープを制限したいのではないでしょうか。環境変数は、コマンドが実行されるのときにコマンドに渡される文字列のリストです。
に
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:値」を出力するはずです。および「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
を使用すると、特殊性が取り除かれます(これらの変数の代入は、それらが戻った後も有効のままです)。
¹厳密に言えば、それは完全に真実ではありません。いくつかの実装では、ローカリゼーション環境変数(LANG
、LOCPATH
、LC_*
...)、GNU実装では、POSIXLY_CORRECT
環境変数を考慮します(env echo --version
とPOSIXLY_CORRECT=1 env echo --version
を比較するGNUシステム)。
あなたはそれを正しくやっていますが、bash構文は誤解しやすいです:echo $TEST
は、echo
にTEST
env varをフェッチしてから出力させますが、そうしません。だから与えられた
export TEST=123
その後
TEST=456 echo $TEST
次のシーケンスが含まれます。
シェルはコマンドライン全体を解析し、すべての変数置換を実行するため、コマンドラインは次のようになります。
TEST=456 echo 123
コマンドの前に一時変数セットを作成するため、TEST
の現在の値を保存し、456で上書きします。コマンドラインは今です
echo 123
残りのコマンドを実行します。この場合、123がstdoutに出力されます(そのため、残っているシェルコマンドはTEST
のtemp値も使用していません)。
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
>>
あなたはこれを使ってこれを機能させることができます:
TEST=foo && echo $TEST