変数をエクスポートせずに単一プロセスのテキストファイル(.env)から変数をロードする方法は?

変数をエクスポートせずに単一プロセスのテキストファイル(.env)から変数をロードする方法は?

注:この一般的なトピックは、複数のSEサイトで面倒に扱われているようです。ただし、すべての詳細を注意深くお読みください。以下に説明されているすべての基準をカバーする質問が見つかりませんでした。

zshまた:以下の例では使用しています。私はPOSIX互換のソリューションをしたいが、それは必ずしも必要な要件ではありません。動作bashし、zsh十分に良いです。

以下は、質問のタイトルを明確にするのに役立つ例です。

次の2つのファイルがあるとしましょう。

% ls -AF
.env    printenv*

% cat printenv
echo $LOCAL_MESSAGE_1
echo $LOCAL_MESSAGE_2

% cat .env
LOCAL_MESSAGE_1="hello world"
LOCAL_MESSAGE_2="goodnight moon"

スクリプトを実行しprintenv、次の内容を確認したいと思いますstdout

hello world
goodnight moon

これらの変数が私の環境にない場合、スクリプトは期待どおりに空白行を印刷します。

% unset LOCAL_MESSAGE_1

% unset LOCAL_MESSAGE_2

% ./printenv


スクリプトを実行する前に変数を設定すると、その変数はスクリプトで使用できますが、単一のプロセスでのみ使用でき、同じシェルで開始された後続のプロセスでは使用できません。

% LOCAL_MESSAGE_1="hello world" LOCAL_MESSAGE_2="goodnight moon" ./printenv
hello world
goodnight moon

% ./printenv


だから私の質問は次のとおりです。次の基準に従って、前の例の動作をどのように複製できますか?

  1. printenvサブシェルではなく、現在のシェルで変更されていない状態で実行されます(ありがとうルーディック) — 所望の出力を得ると同時に
  2. ファイルから変数をロードする.envと同時に
  3. このプロセスで呼び出されたローカル変数を保持します。この変数は、シェル環境とその後のプロセスで設定されていないままです。unset必要ない

これを行うためにどのような1行構文を使用できますか?上記の基準を満たすには、次の疑問符を置き換えるために何を使用する必要がありますか?

% ?????????? ./printenv
hello world
goodnight moon

答え1

サブシェル(in)で実行してみましたかbash?良い

( . .env; . ./printenv )
hello world
goodnight moon

これにより、printenvスクリプトにLOCAL変数のみが設定され、親シェルの環境は変更されません。

新しい拡張要件(サブシェルなし)に従って(人気がなく危険な)アプローチを試してくださいeval

eval $(< .env) ./printenv
hello world
goodnight moon

変数定義とコマンドを 1 行に入れて、その行を実行しますeval

答え2

そしてrunenv(これは次のパッケージの一部です。犯人- 別名加害者):

runenv env_file command

〜する
command変更なしで(サブシェルではなく)現在のシェルで実行し、目的の出力を取得すると同時に変数をロードし、そのプロセスenv_file呼び出しのローカル変数を保持します。です。プロセス中に未設定のまま残っている項目は設定を解除する必要はありません。

答え3

「.script」構文を使用して、シェルにスクリプトを提供できます。

。 .env && ./printenv

printenvスクリプトの先頭に「..env」を追加することもできます。これでprintenvを実行できます。

./printenv

"printenv"はシェルで使用されるので、良い名前の選択ではありません。

関連情報