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