答え1
あなたの仮定はシェル変数です環境で。これは正確ではありません。このexport
コマンドは環境の名前を定義します。したがって:
a=1 b=2
export b
最新の結果ですシェル$a
1と2に拡張されることを知っていますが、子プロセスは環境の一部ではないため(現在のシェルでも)$b
何も知りません。a
いくつかの便利なツール:
set
:現在のシェルのパラメータを表示するために使用されます(エクスポートまたはエクスポートされません)。set -k
:セット指定されたパラメータ環境で。考えるf() { set -k; env; }; f a=1
set -a
:環境に設定された名前を入力するようにシェルに指示します。export
すべてのミッション前と同様に。のようなファイルに.env
便利ですset -a; . .env; set +a
。export
:環境に名前を入力するようにシェルに指示します。エクスポートと割り当てはまったく異なる操作です。env
:外部コマンドとして、env
次の事項のみを通知できます。遺伝学したがって、完全性検査に役立ちます。env -i
: 子プロセスを開始する前に環境を整理するのに役立ちます。
代替計画export
:
name=val command
#コマンドの前に割り当てると、名前がコマンドとしてエクスポートされます。declare/local -x name
# 名前をエクスポートします。特に、名前が外部スコープに公開されないようにする場合は、シェル関数に役立ちます。set -a
#次の各ジョブをエクスポートします。
やる気
では、なぜシェルには独自の異なる変数と環境が必要なのですか?もちろん、いくつかの歴史的な理由があると確信していますが、主な理由は範囲指定のためだと思います。この環境は子プロセス用ですが、子プロセスをフォークしなくてもシェルで多くの操作を実行できます。ループを繰り返すとしましょう。
for i in {0..50}; do
somecommand
done
somecommand
を含むi
環境を必要以上に大きくしてメモリを無駄にするのはなぜですか?シェルで選択した変数名がプログラムが意図しないことを意味する場合はどうなりますか? (私が個人的に好きな名前にはDEBUG
.とがありますVERBOSE
。これらの名前はどこにいても名前空間はほとんどありません。)
シェルでなければどのような環境ですか?
時々、Unixの動作を理解するためにカーネルやオペレーティングシステムと対話するための基本的なAPIであるシステムコールを見てください。ここでは、exec
子プロセスを作成するときにシェルで使用される一連の呼び出しを見てみましょう。これはから来たものですマンページexec(3)
(強調):
execle()
関数を使用すると、execvpe()
呼び出し側はenvpパラメーターを介してプログラムが実行される環境を指定できます。 envpパラメーターは、NULLで終わる文字列へのポインター配列であり、NULLポインターで終わる必要があります。他の関数は、呼び出しプロセスの外部変数environから新しいプロセスイメージの環境を取得します。
したがって、シェルに書き込むことは、Cのグローバル辞書export somename
に名前をコピーするのと同じです。environ
ただし、somename
エクスポートせずに割り当てるのは、Cから変数にコピーせずに割り当てるのと同じですenviron
。
答え2
シェル変数と環境変数には違いがあります。シェル変数を指定せずに定義すると、export
その変数はプロセス環境に追加されず、その子プロセスに継承されません。
export
環境に追加するようにシェルに指示したシェル変数を使用します。以下を使用してテストできます。printenv
(環境を に印刷してstdout
サブプロセスなのでexport
ing 変数の効果を見ることができます。)
#!/bin/sh
MYVAR="my cool variable"
echo "Without export:"
printenv | grep MYVAR
echo "With export:"
export MYVAR
printenv | grep MYVAR
答え3
変数をエクスポートすると、その変数は環境の一部になります。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
答え4
簡単に言うと:
- プロセスは親プロセスから環境変数を継承します。
- Bashでは、$ a = 1は環境変数ではなく「一般」変数を生成します。
- エクスポートa = 1はターミナルプロセスの環境変数を生成します(他の方法があります)
- 環境データを子プロセスに渡す他の方法はありますか?