環境変数とコマンドの間にセミコロンを使用する場合

環境変数とコマンドの間にセミコロンを使用する場合

LANGbash によって更新されたと認識されるためにセミコロンが必要な理由を説明できる人はいますか?

動作しません:

> LANG=Ja_JP bash -c "echo $LANG"
en_US

作品:

> LANG=Ja_JP ; bash -c "echo $LANG"
Ja_JP

私はLinux上のbash 4.1.10とcygwin上の同じバージョンの両方を使用しています

答え1

パラメータやその他の種類の拡張はコマンドが読み取られるときに実行されます。前に実行されます。

最初のバージョン はLANG=Ja_JP bash -c "echo $LANG"単一のコマンドです。 このように解析された後、何かが実行される前に$LANGが に展開されます。 が入力の処理を終了すると、プロセスをフォークし、期待どおりに環境に追加してから を実行します。en_USbashLANG=Ja_JPbash -c echo en_US

LANG=Ja_JP bash -c 'echo $LANG'一重引用符 (例:出力)を使用すると、展開を防ぐことができますJa_JP

コマンドの一部として変数の割り当てがある場合、その割り当てはそのコマンドの環境にのみ影響し、シェルの環境にには影響しないことに注意してください。

2 番目のバージョンは、LANG=Ja_JP; bash -c "echo $LANG"実際には 2 つの別々のコマンドが順番に実行されます。最初のバージョンはコマンドなしの単純な変数割り当てなので、現在のシェルに影響します。

したがって、表面的には 1 つの の違いがあるにもかかわらず、2 つのスニペットは根本的に異なります;

.UTF-8完全に話題から外れますが、 when 設定を追加することをお勧めしますLANG。 21 世紀の今日では、Unicode を使用しないことには正当な理由はありません。

答え2

VAR=value; somecommandは以下と同等である

VAR=value
somecommand

これらは、次々に実行される無関係なコマンドです。最初のコマンドは、シェル変数 に値を割り当てますVAR。 がVARすでに環境変数でない限り、それは環境にエクスポートされず、シェルの内部に残ります。 ステートメントは、 を環境にexport VARエクスポートします。VAR

VAR=value somecommandは異なる構文です。 割り当てはVAR=value環境に対して行われますが、この割り当ては の実行環境でのみ行われsomecommand、シェルのその後の実行では行われません。

例:

# Assume neither VAR1 nor VAR2 is in the environment
VAR1=value
echo $VAR1                        # displays "value"
env | grep '^VAR1='               # displays nothing
VAR2=value env | grep '^VAR2='    # displays "VAR2=value"
echo $VAR2                        # displays nothing

答え3

これは私が調査から収集した内容の要約です:

環境変数とシェル変数の 2 つのタイプがあります。

環境変数は、プログラムとその子プログラム/プロセス/サブシェルで使用できます。シェル変数は現在のシェルでのみ使用できます。

https://askubuntu.com/a/26322/326584

まずecho $VAR仕組み

ターミナル/シェル/bash が $ 記号を認識するたびに、「パラメータ展開」と呼ばれる処理が行われます。つまり、変数が値に置き換えられます。

https://www.gnu.org/software/bash/manual/html_node/Shell-Parameter-Expansion.html

したがって、VAR値が 'hello' の場合は にecho $VARなりますecho 'hello'

つまり、これは機能します...

TEST=123 
echo $TEST
// 123

ただし、コマンドが変数を設定する前に変数が置き換えられたため、以下は機能しません。

TEST2=999 echo $TEST2
// nothing...

ただし、セミコロンを追加すると...

TEST2=999; echo $TEST2

それは同じです。

TEST2=999
echo $TEST2

.. 以前と同じように動作します。

また、シェル変数はサブプロセス/子に渡されないため、コマンドを呼び出すと新しいプロセスが作成されます。

TEST3=111 
node -e 'console.log(process.env.TEST3)' 

または

TEST3=111 
printenv TEST3

どちらも何も出力しません。シェル変数は chld プロセスによって継承されません。シェル変数を環境変数にするには、export を使用します。

export TEST3=111 
printenv TEST3
//111

例外が1つあります...

VAR=123 printenv VAR
VAR=123 VAR2=456 printenv VAR2 //even multiple vars

基本的にこのように記述してコマンドを呼び出した直後は、そのコマンドの環境変数が一時的に設定されるだけです。シェル変数も設定されません。完全に新しい構文と考えてください。

VAR=123 printenv VAR // 123
echo $VAR // nothing
VAR=123
echo $VAR // 123

関連情報