プロセスが親の環境を継承する場合、なぜエクスポートする必要があるのですか?


72

ここexportで、シェルでの目的は、シェルから開始されたサブプロセスで変数を使用可能にすることであることを読みました。

しかし、私はまた、読んだことが、ここここにいることを「プロセスがその親(それを開始したプロセス)から自分の環境を継承します。」

この場合、なぜ必要なのexportですか?私は何が欠けていますか?

シェル変数はデフォルトで環境の一部ではありませんか?違いはなんですか?

回答:


74

あなたの仮定は、シェル変数が環境にあるということです。これは間違っています。このexportコマンドは、環境内に存在する名前を定義するものです。副<文>この[前述の事実の]結果として、それ故に、従って、だから◆【同】consequently; therefore <文>このような方法で、このようにして、こんなふうに、上に述べたように◆【同】in this manner <文>そのような程度まで<文> AひいてはB◆【用法】A and thus B <文>例えば◆【同】for example; as an example:

a=1 b=2
export b

現在のシェル$aは1と$b2に展開することを認識しますが、サブプロセスはa環境の一部ではないため(現在のシェルでも)、何も認識しません。

便利なツール:

  • set:現在のシェルのパラメーターを表示するのに便利、エクスポートされているかどうか
  • set -k:環境内の割り当てられた引数を設定します。検討するf() { set -k; env; }; f a=1
  • set -a:環境に設定される任意の名前を付けるようシェルに指示します。exportすべての課題の前に置くのが好きです。のように、.envファイルに便利ですset -a; . .env; set +a
  • export:環境に名前を付けるようシェルに指示します。エクスポートと割り当ては、まったく異なる2つの操作です。
  • env:外部コマンドとして、継承された環境envについてのみ伝えることができるため、健全性チェックに役立ちます。
  • env -i:サブプロセスを開始する前に環境をクリアするのに役立ちます。

の代替export

  1. name=val command #コマンドの前の割り当ては、その名前をコマンドにエクスポートします。
  2. declare/local -x name #名前をエクスポートします。名前を外部スコープに公開しないようにする場合にシェル関数で特に役立ちます。
  3. set -a #次のすべての割り当てをエクスポートします。

3
set -kcmd ENVVAR=valueはの代わりに使用できるようにするために、呼び出す前に実行しENVVAR=value cmdない限りあなたの例では動作しません。また、最近では多くのシェルがサポートしておらず、Bourneシェルとの後方互換性のためだけにサポートされています。Bourne(またはKorn)シェルでは、関数では機能しません。そして、それはシェルの構文解析に影響するため、シェルがそれを使用するコードをそこで読み取るときに有効でなければなりません。set -kf
ステファンシャゼル

1
また、言及することをお勧めしますset -a
ステファンChazelas

24

シェル変数と環境変数には違いがあります。シェル変数をexporting なしで定義すると、プロセス環境に追加されないため、その子には継承されません。

を使用しexportて、シェルに環境にシェル変数を追加するよう指示します。これをテストするにはprintenv(環境をstdoutに出力するだけexportです)子プロセスなので、変数の効果を確認できます:

#!/bin/sh

MYVAR="my cool variable"

echo "Without export:"
printenv | grep MYVAR

echo "With export:"
export MYVAR
printenv | grep MYVAR

6

エクスポートされた変数は、環境の一部です。PATHはシェル自体にエクスポートされますが、カスタム変数は必要に応じてエクスポートできます。いくつかのセットアップコードの使用:

$ cat subshell.sh 
#!/usr/bin/env bash
declare | grep -e '^PATH=' -e '^foo='

比較する

$ cat test.sh 
#!/usr/bin/env bash
export PATH=/bin
export foo=bar
declare | grep -e '^PATH=' -e '^foo='
./subshell.sh
$ ./test.sh 
PATH=/bin
foo=bar
PATH=/bin
foo=bar

$ cat test2.sh 
#!/usr/bin/env bash
PATH=/bin
foo=bar
declare | grep -e '^PATH=' -e '^foo='
./subshell.sh
$ ./test2.sh 
PATH=/bin
foo=bar
PATH=/bin

fooはシェルによってエクスポートされず、エクスポートされないため、前回の実行時のtest2.sh環境の一部ではありませんでしたsubshell.sh

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.