GNU/Linux >> Linux の 問題 >  >> Linux

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

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

ただし、こことここで、「プロセスは親(プロセスを開始したプロセス)から環境を継承する」ことも読みました。

この場合、なぜexportが必要なのですか。 ?何が足りないのですか?

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

承認された回答:

あなたの仮定は、シェル変数が環境内にあるということです。 。これは正しくありません。 export コマンドは、環境内に存在する名前を定義するものです。したがって:

a=1 b=2
export b

結果は現在のシェルになります その$aを知っている 1に展開され、$b 2になりますが、サブプロセスは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 #次のすべての割り当てをエクスポートします。

モチベーション

では、なぜシェルは独自の変数と異なる環境を持つ必要があるのでしょうか。歴史的な理由はいくつかあると思いますが、主な理由はスコーピングだと思います。環境はサブプロセス用ですが、サブプロセスをフォークせずにシェルで実行できる操作はたくさんあります。ループするとします:

for i in {0..50}; do
    somecommand
done

somecommandのためにメモリを浪費する理由 iを含める 、その環境を必要以上に大きくしますか?シェルで選択した変数名が、プログラムに意図されていない何かを意味している場合はどうなりますか? (私の個人的なお気に入りには、DEBUGが含まれます およびVERBOSE 。これらの名前はどこでも使用されており、名前付けが適切に行われることはめったにありません。)

関連:xevからのこの出力はどういう意味ですか?

シェルでない場合の環境は何ですか?

Unixの動作を理解するには、カーネルやOSと対話するための基本的なAPIであるsyscallsを調べる必要がある場合があります。ここでは、execを見ています。 呼び出しのファミリー。これは、シェルがサブプロセスを作成するときに使用するものです。 exec(3)のマンページからの引用です。 (私の強調):

execle() およびexecvpe() 関数を使用すると、呼び出し元は引数envpを介して実行されたプログラムの環境を指定できます。 envp引数は、nullで終了する文字列へのポインタの配列であり、NULLポインタで終了する必要があります。 他の関数は、呼び出しプロセスの外部変数environから新しいプロセスイメージの環境を取得します。

したがって、export somenameと書く シェル内では、名前をグローバルディクショナリenvironにコピーするのと同じです。 Cで。ただし、somenameを割り当てる エクスポートせずに、environにコピーせずに、Cで割り当てるのと同じようになります。 変数。


Linux
  1. Bashシェルのカスタマイズ

  2. 環境変数を設定するための最良のディストリビューション/シェルにとらわれない方法は何ですか?

  3. 〜/ .bash_profileが機能しないのはなぜですか?

  1. シェルスクリプトの「sudoSu」がスクリプトの残りの部分をルートとして実行しないのはなぜですか?

  2. 子プロセスのPgidが親のPidではないのはなぜですか?

  3. ルートユーザーがSudo権限を必要とするのはなぜですか?

  1. Zsh配列の最初の要素が0ではなく1でインデックス付けされる理由

  2. Linuxディスプレイをエクスポートできないのはなぜですか?

  3. Python で親プロセスの環境を変更することは可能ですか?