コマンドラインで環境変数を設定してコマンドに表示するにはどうすればよいですか?

コマンドラインで環境変数を設定してコマンドに表示するにはどうすればよいですか?

走れば

export TEST=foo
echo $TEST

fooを出力します。

走れば

TEST=foo echo $TEST

いいえ。エクスポートやスクリプトを使用せずにこの機能を取得するにはどうすればよいですか?

答え1

これは、シェルがコマンドラインから変数を拡張するためです。今後実際にコマンドを実行しますが、この時点では変数は存在しません。使用する場合

TEST=foo; echo $TEST

動作します。

export後で実行されるコマンドの環境に変数が表示されます(bashでこれがどのように機能するかについては、参照help export)。 1つのコマンド環境にのみ変数を表示する必要がある場合は、試した方法を使用してください。

TEST=foo your-application

シェル構文はこれを次のように説明します。機能的に以下と同じ:

export TEST=foo
your-application
unset TEST

バラより仕様もっと学ぶ。

興味深いことに、このexportコマンドは変数のエクスポートフラグを切り替えます。名前。その場合は、次のようにしてください。

unset TEST
export TEST
TEST="foo"

TESTエクスポート時に定義されていない場合でもエクスポートされます。ただし、unsetエクスポートした属性はここで削除する必要があります。

答え2

欲しいと思うシェル変数は環境変数ではなく限られた範囲を持っています。環境変数は、コマンドに渡された文字列のリストです。処刑された

存在する

var=value echo whatever

var=value文字列をエコー受信環境に渡します。ただし、echo環境リストには何も実行されず、ほとんどのシェルにはechoとにかく組み込まれているため、そうしません。処刑された

書いたら

var=value sh -c 'echo "$var"'

もう一つの話です。ここではコマンドを渡し、var=valueその環境を使用します。シェルは環境から受け取ったすべての変数をシェル変数に変換するので、受け取った環境変数は変数に変換され、そのコマンドラインから拡張すると環境がデフォルトで継承されるためになります。また、その環境で受信されますが(または実行されている場合)、環境については気にしません。shshvarsh$varechoecho valueechovar=valueecho

今私が考えているように、シェル変数の範囲を制限したい場合は、いくつかの可能な方法があります。

ポータブル(BourneとPOSIX):

(var=value; echo "1: $var"); echo "2: $var"

(...)上記はサブシェル(ほとんどのシェルで新しいシェルプロセス)を開始するため、ここで宣言されたすべての変数はそのサブシェルにのみ影響するため、上記のコードでは「1:value」と「2:」または " 2: 以前に設定されたすべての変数"。

ほとんどのBourne型シェルの場合(参照)ローカル変数を定義するために「local」キーワードをサポートするシェルのリスト)、関数と「ローカル」組み込み機能を使用できます。

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、、、mkshyashで動作するが動作しないバリエーション(/エミュレーションzshを除く):shksh

var=value command eval 'echo "1: $var"'; echo "2: $var"

(POSIXシェルのcommand特別な組み込み関数(ここ)の前でこれを使用すると、eval特殊性が削除されます(ここで先行変数の割り当ては戻り後も有効です)。

fishシェルを使用すると、変数をbegin..endブロックにローカルに設定できます。

begin
  set -l var value
  echo 1: $var
end
echo 2: $var

mksh(そしてすぐにzshを使用すると、ローカルスコープも持つ可能性がある${|cmd}この設定を乱用し、次のスコープ$REPLYで設定しないようにしてnullに拡張することができます。

${|local var=value; echo "$var"}; echo "$var"

厳密に言えば、これは完全に真実ではありません。一部の実装はローカライズされた環境変数(LANG、、、LOCPATH... LC_*)に興味があり、GNU実装はPOSIXLY_CORRECT環境変数(GNUシステムとは異なり)env echo --versionに興味があります。env POSIXLY_CORRECT=1 echo --version

答え3

正しく実行していますが、bash構文は簡単に誤解されます。これにより、env varをインポートしてから印刷することにecho $TESTなると思いますが、そうではありません。だから与えられたechoTEST

export TEST=123

それから

TEST=456 echo $TEST

次の順序が含まれます。

  1. シェルはコマンドライン全体を解析し、すべての変数置換を実行するので、コマンドラインは次のようになります。

    TEST=456 echo 123
    
  2. コマンドの前に一時変数セットを作成するので、現在の値を保存してTESTコマンドラインを456で上書きします。

    echo 123
    
  3. 残りのコマンドを実行します。この場合、標準出力に123を印刷します(したがって、残りのシェルコマンドに一時値は使用されませんTEST)。

  4. 価値を回復させる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
>>

答え4

すでに見つけたように、BashではTEST=456 echo $TESTシェルが現在解釈している同じ行の変数にアクセスしているため、期待どおりに動作しません。でも心配しないでください。変数は、現在のコマンドが継続している間に設定されます。これを確認するには、次のようにします。

show () { echo "${!1}" ;}
TEST=456 show TEST

関連情報