환경 변수를 안전하게 저장하고 복원합니다.

환경 변수를 안전하게 저장하고 복원합니다.

.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

관련 정보