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

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

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_USたら、プロセスを分岐して期待どおりに環境に追加してから実行します。bashLANG=Ja_JPbash -c echo en_US

LANG=Ja_JP bash -c 'echo $LANG'拡張を防ぐために、単一引用符(出力など)を使用できますJa_JP

コマンドの一部として変数を割り当てると、割り当てはシェル環境ではなくコマンド環境にのみ影響します。

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

したがって、シングル;

完全に話題から抜け出しましたが、.UTF-8最近LANG21世紀には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 TEST3=111 
printenv TEST3
//111

1つの例外があります。

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

デフォルトでは、これを作成してコマンドを呼び出した直後に設定すると、そのコマンドの環境変数のみが一時的に設定されます。シェルvarも設定しません。まったく新しい構文だと思います。

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

関連情報