
LANG
bash によって更新されたと認識されるためにセミコロンが必要な理由を説明できる人はいますか?
動作しません:
> 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
bash
LANG=Ja_JP
bash -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