私は here を読みました。シェルでのexport
の目的は、シェルから開始されたサブプロセスで変数を使用できるようにすることです。
しかし、私は here および here that「プロセスは親(プロセスを開始したプロセス)から環境を継承します」も読んだ。
この場合、export
が必要なのはなぜですか?何が欠けていますか?
シェル変数はデフォルトで環境の一部ではありませんか?違いはなんですか?
シェル変数は環境内であると想定しています。これは誤りです。 export
コマンドは、環境に存在する名前を定義するものです。したがって:
_a=1 b=2
export b
_
結果は現在のShellであり、_$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
はinherited環境についてのみ通知できるため、健全性チェックに役立ちます。env -i
_:サブプロセスを開始する前に環境をクリアするのに役立ちます。export
の代替:
name=val command
_#コマンドの前の割り当ては、その名前をコマンドにエクスポートします。declare/local -x name
_#名前をエクスポートします。特に、名前をスコープ外に公開したくない場合にシェル関数で役立ちます。set -a
_#次のすべての割り当てをエクスポートします。シェル変数と環境変数には違いがあります。 export
ingなしでシェル変数を定義すると、その変数はプロセス環境に追加されないため、その子には継承されません。
export
を使用して、シェルにShell変数を環境に追加するように指示します。これは、printenv
を使用してテストできます(これは、環境をstdout
に出力します。これは、export
ing変数の影響を見る子プロセスであるためです)。
#!/bin/sh
MYVAR="my cool variable"
echo "Without export:"
printenv | grep MYVAR
echo "With export:"
export MYVAR
printenv | grep MYVAR
変数は、エクスポートされると環境の一部になります。 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
の環境の一部ではありませんでした。