環境変数を安全に保存して復元します。

環境変数を安全に保存して復元します。

.env追加のアクションを実行する前に、基本ファイルを解析してその内容を環境変数にエクスポートするスクリプトがあります。

set -eu

test -f .env && load_dotenv

exec ./foobar x y z "$@"

ただし、これにより定義された環境変数は、.envユーザーシェルで定義されている環境変数よりも優先されます。私は反対の行動が欲しい。つまり、シェルに明示的に設定された環境変数は、ファイルで定義されているものよりも優先したいと思います.env

load_dotenvしたがって、実行する前に現在の環境を「保存」し、実行後に保存した環境を「再適用」したいと思いますload_dotenv

set -eu

user_env="$( env )"

test -f .env && load_dotenv

reapply_env "$user_env"  # ???

exec ./foobar x y z "$@"

reapply_env任意の環境変数を処理できるようにこれをどのように実装しますか?私が知っている限り、それ以上のすべてのバイトは\0環境変数で有効なので、これが任意の環境変数に対して機能することを確認したいと思います。たとえば、環境変数に改行文字を挿入する正当な(一般的ではありません)ユースケースがあります。

私はシェル関連の回答に開いていますが、Bourneスタイルのシェル(Bash、Ksh、Zshなど)を使用しているとします。

セキュリティ問題を無視してください。信頼性が高く管理された環境で作業しており、.env「開発者をだまして悪意のあるファイルをダウンロードする」などのシナリオには、この質問の範囲外の広範なセキュリティ問題が含まれていると想定しています。

編集:環境変数のオーバーライドを避ける方法は良い質問ですが、この特定の質問に対する回答に興味があるわけではありません。まだ重複していない場合は、別の投稿を投稿できます。

答え1

Bashには、環境変数を設定する前にテストする機能があります。したがって、.env次のようにファイルを作成できます。

VAR1="default value"
VAR2=${VAR2:="default value"}

新しいセッション(バッチまたはターミナル)がある場合は、次の手順を実行します。

$ source .env
$ echo $VAR1 - $VAR2
default value - default value
$ VAR1="my value"
$ VAR2="my value"
$ source .env
$ echo $VAR1 - $VAR2
default value - my value

構文は次のように説明されます。https://www.gnu.org/software/bash/manual/bash.html#Shell-Parameter-Expansion

kshどちらもzsh同様の機能を持ち、「変数が存在しない場合は変数に値を割り当てる」操作と同じ構文を持ちます。

https://www.ibm.com/docs/en/aix/7.1?topic=shell-parameter-substitution-in-korn-posix

https://zsh.sourceforge.io/Doc/Release/Expansion.html#Parameter-Expansion

答え2

Bashでは(最小サポートバージョンは不明です)、export組み込み関数はeval-edまたは-dが可能なsource有効なスクリプトをエクスポートします。

#!/usr/bin/env bash

export FOO=$'a\nb'

export > ./user-env.bash

env -u FOO bash -c '
source ./user-env.bash ;
sh -c "printf \"%q\n\" \"$FOO\""
'

出力は次のようになります。

$'a\nb'

Zshも有効なスクリプトをエクスポートします。いいえ各行の先頭には、exportBashバージョンを含むすべての宣言が含まれています。declare -xだから私はまだZshソリューションを探しています。

答え3

Linuxを使用している場合は、次の内容を読んで/proc/self/environ環境変数を保存できます。

myenv=()
while IFS= read -d '' -r var; do
  myenv+=("$var");
done < /proc/self/environ

次に、envファイルをロードし、その配列を使用して値をリセットします(変数名にその配列が含まれていないと仮定=)。

for i in "${myenv[@]}";
do
  export "$i";
done

関連情報