
.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も有効なスクリプトをエクスポートします。いいえ各行の先頭には、export
Bashバージョンを含むすべての宣言が含まれています。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