連続ソース使用間の持続的な環境変数の理論的根拠

連続ソース使用間の持続的な環境変数の理論的根拠

コンテキスト:

  • オペレーティングシステム:オープン水勢の飛躍 15.1
  • コア:Linux 4.12.14-lp151.27-基本
  • シェル:GNU bash、バージョン 4.4.23(1)-リリース(x86_64-suse-linux-gnu)

次のスクリプトが与えられたら、test.shと呼びます。:

#!/bin/bash -e
echo "$TEST_VAR"

他の実行では、次を返します。

TEST_VAR=1234; source test.sh->出力:1234

source test.sh -> 出力:1234

質問:

  • なぜenvの価値テスト変数実行の間に持続しますか(env | grep -i test_var)何も返しません)?
  • このようなものを使用するのではなく、これを防ぐ方法はありますかexec bash
  • 以前の質問に対する答えが「はい」の場合、少なくともどのくらいのクロスシェルであるソリューションがありますか?

ありがとうございます。

答え1

source(同義語.(指す)〜する

現在の環境でコマンドを実行する

つまり、test.sh独自の変数を持つ新しいシェルでは実行されず、単に現在のシェルの各コマンドを実行します。特に、これは#!/bin/bash -eコメントとして扱われるシェバンを無効にします。スクリプトを次に変更する場合

set -e
echo "$TEST_VAR"
false

source戻りコードはそのため、対話型セッションはすぐに終了しますfalse。現在のシェルの出力をどこかに保存しないと、結果としてすべてのエラーメッセージが失われます(これは重要ではありませんが、false実際のスクリプトには重要です)。失敗する可能性のあるスクリプトを実行するsourceためにこの組み合わせを使用しないことをお勧めします。set -e

TEST_VAR=1234; source test.sh単にコマンドを分離するため、TEST_VAR値は保持されます。;TEST_VAR=1234; source test.sh

TEST_VAR=1234
source test.sh

それは単なる課題TEST_VARと通貨ですsourcesource現在の環境でコマンドが実行されるため、TEST_VARその環境で使用できます。

;存在しない場合は、TEST_VAR次のコマンド呼び出しに対してのみ割り当てを有効にして変更できますsource

$ cat test.sh
#!/bin/bash -e
echo $TEST_VAR
$ TEST_VAR=1234 source test.sh
1234
$ source test.sh

env | grep -i test_var何も返さない

その理由は次のように説明されています。https://unix.stackexchange.com/a/268258/4699:

envは外部コマンド(シェル組み込みコマンドとは反対)なので、envはシェルからエクスポートされた変数のみを印刷します。

反対側のセットには、すべてのシェル変数が一覧表示されます。それらのいくつかは輸出されます。

エクスポートは、シェルからエクスポートされたシェル変数を一覧表示します。

exportセット変数のエクスポートにも使用できます。

$ TEST_VAR=1234; source test.sh
1234
$ set | grep TEST
TEST_VAR=1234
$ env | grep TEST
$ export TEST_VAR
$ env | grep TEST
TEST_VAR=1234

答え2

スクリプトに使用されるか、source現在の.シェル環境で実行されます。

これは、現在のシェルで使用可能なすべてのシェル変数がドットスクリプト(インポートスクリプト)でも使用可能であることを意味します。これはまた、#!スクリプトの - 行が完全に無視されることを意味します。

表示するコマンドは変数をTEST_VAR値に設定します。次に、そのシェル変数にアクセスできるドットスクリプトを取得し、インポートした後にその値を印刷します。

その後、同じドットスクリプトを再取得します。unset最後に、スクリプトのインポート後にシェル変数が明示的に表示されなかったため、値が再印刷されます。

envあなたは+パイプから何の出力も得られませんgrep環境このパターンに一致する変数です。これはTEST_VAR決して環境にエクスポートされず、厳密にはシェル変数であるため、子プロセス(たとえばenv)によって継承されません。

スクリプトを通常のスクリプトとして実行すると、つまりを使用して実行可能になり、実行するとスクリプトのchmod +x test.sh変数値が空であること./test.shがわかります。TEST_VARこれは、スクリプトが呼び出しシェルのシェル変数にアクセスできず、現在の環境に呼び出し環境変数がないためです(TEST_VAR+パイプラインに呼び出し環境変数がないように)。envgrep

以下を使用して既存のTEST_VARシェル変数をエクスポートすると、値を環境変数としてスクリプトにインポートできます。export TEST_VAR

TEST_VAR=$TEST_VAR ./test.sh

または

env TEST_VAR="$TEST_VAR" ./test.sh

関連情報