web-dev-qa-db-ja.com

プログラムの実行と同じ行に環境変数を設定することは、個別に設定することとは異なりますか? -シェル変数と環境変数

違いは何ですか:

Prompt$   TSAN_OPTIONS="suppressions=/somewhere/file" ./myprogram

そして

Prompt$   TSAN_OPTIONS="suppressions=/somewhere/file"
Prompt$   ./myprogram

thread-sanitizer ライブラリは、オプションで指定されたファイルを読み取るためにライブラリ(myprogram内で使用)を取得する方法として最初のケースを示します。私はそれを読み、2行に分かれていると想定して、2番目のケースとして実行しました。

ライブラリは、環境変数とプログラム実行が別々の行にある2番目のケースではファイルを使用しません。

違いは何ですか?

おまけの質問:最初のケースはどのようにエラーなしで実行されますか?あるべきではありません。またはそれらの間の&&?この質問への答えはおそらく私の最初の答えです...

24
user1902689

形式VAR=value commandは、コマンドVARの環境で変数valueを値commandに設定します。これをカバーするスペックセクションは 単純なコマンド です。具体的には:

それ以外の場合、変数の割り当てはコマンドの実行環境用にエクスポートされ、手順4で実行された拡張の副作用を除いて、現在の実行環境に影響を与えません。

形式VAR=value; commandは、シェル変数VAR現在のシェルに設定し、commandをとして実行します。子プロセス。子プロセスは、シェルプロセスで設定された変数について何も知りません。

プロセスが変数をエクスポート(ヒント)して、子プロセスから見えるようにするメカニズムは、子プロセスを実行する前に、その環境で変数を設定することです。これを行う組み込みシェルは export です。これが、export VAR=valueVAR=value; export VARがよく見られる理由です。

あなたが議論している構文は、次のようなものの短縮形です。

VAR=value
export VAR
command
unset -v VAR

現在のプロセス環境をまったく使用せずにのみ。

29
Etan Reisner

補足するために Etan Reisnerの有用な答え

Shell変数とenvironment変数を区別することが重要

注:以下はallPOSIX互換シェルに適用されます。 bash固有の拡張子はそのようにマークされています。

Shellvariableは、それを定義するシェルに限定されたシェル固有の構成です(subshel​​ls、現在のシェルの変数の独自のcopiesを取得します)、
environmentvariable任意の子プロセスに継承されますその子プロセス自体がシェルであるかどうかに関係なく、現在のプロセス(シェル)によって作成されます。
すべて大文字の変数名はenvironment変数 にのみ使用する必要があることに注意してください。

いずれにせよ、子プロセスは変数のcopysのみを継承し、その変更(子による)はnotparentに影響します。

  • すべてのenvironment変数はalsoShell変数(シェルはそれを保証します)、
  • しかしinverse is not trueShell変数は環境変数ではありません、明示的に指定しない限り-この指定はexporting。と呼ばれます
    • デフォルトではオフの-aシェルオプション(set -aで設定するか、コマンドラインオプションとしてシェル自体に渡す)を使用してにすることができることに注意してください。自動エクスポートすべてのシェル変数。

したがって、

  • 割り当てによってimplicitlyで作成した変数-例:TSAN_OPTIONS="suppressions=/somewhere/file"-はシェル変数のみですが、環境変数でもありません。
  • ただし-おそらく紛らわしい-コマンドの前に直接追加された場合-例TSAN_OPTIONS="suppressions=/somewhere/file" ./myprogram-この場合、それらはenvironment変数のみ、そのコマンドに対してのみ有効
    • これがエタンの答えが説明していることです。

シェル変数は、次の状況では環境変数同様にになります。

  • $HOMEなど、シェル自体が継承した環境変数に基づく
  • export varName[=value]で明示的に作成されたシェル変数、またはbashで、declare -x varName[=value] でも作成されたシェル変数
    • 対照的に、bashでは、-xなしでdeclareを使用するか、関数でlocalを使用すると、単なるShell /が作成されます変数
  • デフォルト以外の-aシェルオプションが有効なときに暗黙的に作成されたシェル変数(一部の例外を除く)

シェル変数がエクスポート済みとしてマークされると-つまり、環境変数としてマークされます-シェル変数への後続の変更により、環境が更新されます同様に変数;例えば。:

export TSAN_OPTIONS  # creates Shell variable *and* corresponding environment variable

# ...

TSAN_OPTIONS="suppressions=/somewhere/file" # updates *both* the Shell and env. var.

  • export -pはすべての環境変数を出力します
  • unset [-v] MYVARはシェル変数$MYVARの定義を解除し、該当する場合は環境変数としても削除します。
  • bash
    • export -n MYVARを使用してShell変数として定義を解除せずに、特定の変数を「エクスポート解除」できます。これにより、環境からMYVARが削除されますが、Shell変数として現在の値を保持します。
    • declare -p MYVARは、変数$MYVARの現在の値とその属性を出力します。出力がdeclare -xで始まる場合、$MYVARがエクスポートされます(環境変数です)
21
mklement0