あるターミナルウィンドウで環境変数を作成し、それを別のターミナルウィンドウにエコーしようとしました。何も表示されませんでした。
$TEST=hello
その後、エクスポートして、別のターミナルウィンドウでecho
を再試行しました。 。結果は以前と同じでした。
export TEST
ただし、ログイン時に同じコードを実行すると(コードを~/.profile
file)変数は、任意のターミナルウィンドウで使用できます。ここで何が起きてるの?ターミナルでコードを実行することと、ログイン時に同じコードを実行することの違いは何ですか?
回答
export
は、子プロセス環境に含まれる変数を作成します。他の既存の環境には影響しません。一般に、ある端末に変数を設定し、それを別の端末に自動的に表示する方法はありません。環境はプロセスごとに独自に確立されます。
を使用すると、ログインするたびに新しい変数が含まれるように環境が設定されます。したがって、あるシェルから別のシェルにエクスポートされるのではなく、新しいシェルに含めるように指示されます。初期環境を設定するときに設定します。
回答
各プロセスには、プロセスが個別に独立して設定できるいくつかの属性があります。他のプロセス。例としては、リソース制限、umask、現在のディレクトリ、環境変数などがあります。プロセスの作成時に(fork()
システムコールを介して)、子はこれらの属性を親から継承します。この後、子プロセスはこれらの属性を任意に設定できます。 (いくつかの制限が適用されます。プロセスはハードリソースの制限を増やしたり、現在のディレクトリをexec権限のないディレクトリに変更したりすることはできません。)
環境変数を変更するプログラムはごくわずかで、ほとんどの場合は気にしません。後者の場合を想定します。したがって、子プロセスがそれ自体にさらに子を作成する場合、これらのプロセスは祖父母と同じ環境変数を持ちます。などなど。
これで、シェルには多くの変数があります。 set
で表示できます(Bourne Shellタイプのシェルでは、C Shellについてはわかりません)。これらの変数は、export
ed。環境変数はenv
で表示できます。シェルコマンドラインからプログラムを起動すると、プログラムはシェルから環境変数を継承します。から起動したプログラムの場合も同様です。シェルスクリプト。
したがって、ログイン時にプロファイルデータを読み取るシェルがあります(例:~/.profile
)そしてそれらを事実上すべての子供、孫などに継承します。これは、環境変数の設定がログインシェルまたはログインスクリプトから、ログインセッション内で起動される他のすべてのプログラムに細流化する方法です。
環境変数を作成しました1つのターミナルウィンドウで、別のターミナルウィンドウにエコーしようとしました。何も表示されませんでした。
上記の説明により、これは期待される結果です。プロセスの環境の変更は、今後作成されるこのプロセスの子にのみ影響し、既存の子には影響しません。
$TEST=hello
変数の展開が無効になっているか、$TEST
にすでに適切な値。 hello
を変数TEST
に割り当てる場合は、TEST=hello
と言う必要があります(注:いいえ$
)。
その後、エクスポートして別のターミナルウィンドウに表示されます。結果は以前と同じでした。
繰り返しになりますが、これは期待される結果です。
ただし、ログイン時に同じコードを実行すると(
~/.profile
ファイルにコードを追加)、任意のターミナルウィンドウで変数を使用できます。
これは、ターミナルのシェルが~/.profile
から環境設定を読み取り、これらの設定を継承したシェルの子孫であるためです。