development

키 / 값 쌍 파일에서 환경 변수 설정

big-blog 2020. 2. 21. 22:29
반응형

키 / 값 쌍 파일에서 환경 변수 설정


TL; DR : 텍스트 파일에서 셸 환경으로 키 / 값 쌍 세트를 내보내려면 어떻게해야합니까?


기록을 위해 아래는 질문의 원래 버전과 예제입니다.

특정 폴더에 3 개의 변수가있는 파일을 구문 분석하는 스크립트를 bash로 작성 중입니다.이 중 하나입니다.

MINIENTREGA_FECHALIMITE="2011-03-31"
MINIENTREGA_FICHEROS="informe.txt programa.c"
MINIENTREGA_DESTINO="./destino/entrega-prac1"

이 파일은 ./conf/prac1에 저장됩니다.

내 스크립트 minientrega.sh는 다음 코드를 사용하여 파일을 구문 분석합니다.

cat ./conf/$1 | while read line; do
    export $line
done

그러나 minientrega.sh prac1명령 줄에서 실행할 때 환경 변수를 설정하지 않습니다

나는 또한 사용하려고 source ./conf/$1했지만 동일한 문제가 여전히 적용됩니다.

어쩌면 이것을 수행하는 다른 방법이있을 수 있습니다. 스크립트의 인수로 전달하는 파일의 환경 변수를 사용해야합니다.


당신의 접근 방식에 문제가있다 export에서 while루프가 서브 쉘에서 일어나고, 그 변수는 현재 쉘 (while 루프의 부모 쉘)에서 사용할 수 없습니다.

export파일 자체에 명령을 추가하십시오 .

export MINIENTREGA_FECHALIMITE="2011-03-31"
export MINIENTREGA_FICHEROS="informe.txt programa.c"
export MINIENTREGA_DESTINO="./destino/entrega-prac1"

그런 다음 다음을 사용하여 현재 셸에서 파일을 소싱해야합니다.

. ./conf/prac1

또는

source ./conf/prac1

도움이 될 수 있습니다.

export $(cat .env | xargs) && rails c

내가 이것을 사용하는 이유는 .env레일 콘솔에서 물건 을 테스트하고 싶기 때문 입니다.

gabrielf 는 변수를 지역적으로 유지하는 좋은 방법을 찾았 습니다. 이것은 프로젝트에서 프로젝트로 갈 때 발생할 수있는 잠재적 인 문제를 해결합니다.

env $(cat .env | xargs) rails

나는 이것을 테스트했다. bash 3.2.51(1)-release


최신 정보:

로 시작하는 줄을 무시하려면 #이것을 사용하십시오 ( Pete 's comment 덕분에 ).

export $(grep -v '^#' .env | xargs)

당신이 원한다면 unset파일에 정의 된 모든 변수, 이것을 사용 :

unset $(grep -v '^#' .env | sed -E 's/(.*)=.*/\1/' | xargs)

최신 정보:

공백이있는 값도 처리하려면 다음을 사용하십시오.

export $(grep -v '^#' .env | xargs -d '\n')

GNU 시스템에서 또는

export $(grep -v '^#' .env | xargs -0)

BSD 시스템에서.


-o allexport다음 변수 정의를 모두 내보낼 수 있습니다. +o allexport이 기능을 비활성화합니다.

set -o allexport
source conf-file
set +o allexport

set -a
. ./env.txt
set +a

다음 env.txt과 같은 경우 :

VAR1=1
VAR2=2
VAR3=3
...

allexport옵션은 몇 가지 다른 답변에 언급되어 set -a있으며 바로 가기입니다. 주석, 빈 줄 및 명령으로 생성 된 환경 변수를 허용하기 때문에 .env를 소싱하는 것은 실제로 줄을 반복하고 내보내는 것보다 낫습니다. 내 .bashrc에는 다음이 포함됩니다.

# .env loading in the shell
dotenv () {
  set -a
  [ -f .env ] && . .env
  set +a
}

# Run dotenv on login
dotenv

# Run dotenv on every new directory
cd () {
  builtin cd $@
  dotenv
}

eval $(cat .env | sed 's/^/export /')

다음은 sedeval을 실행하지 않거나 루비가 필요한 다른 솔루션입니다.

source <(sed -E -n 's/[^#]+/export &/ p' ~/.env)

이것은 주석으로 시작하는 행에 주석을 유지하면서 내보내기를 추가합니다.

.env 내용

A=1
#B=2

샘플 런

$ sed -E -n 's/[^#]+/export &/ p' ~/.env
export A=1
#export B=2

나는 이것을 사용하여 시스템 단위 파일EnvironmentFile 에로드 할 파일을 만들 때 특히 유용하다는 것을 알았 습니다 .


user4040650의 대답은 간단하기 때문에 파일의 주석 (예 : #으로 시작하는 줄)을 허용합니다. 변수를 설명하는 주석을 추가 할 수 있기 때문에 나에게 매우 바람직합니다. 원래 질문의 맥락에서 다시 작성하십시오.

표시된대로 스크립트를 호출하면 minientrega.sh prac1minientrega.sh는 다음을 가질 수 있습니다.

set -a # export all variables created next
source $1
set +a # stop exporting

# test that it works
echo "Ficheros: $MINIENTREGA_FICHEROS"

다음은 세트 문서 에서 추출되었습니다 .

이 내장은 너무 복잡하여 자체 섹션이 필요합니다. set을 사용하면 쉘 옵션의 값을 변경하고 위치 매개 변수를 설정하거나 쉘 변수의 이름과 값을 표시 할 수 있습니다.

[--abefhkmnptuvxBCEHPT] [-o option-name] [argument…] set [+ abefhkmnptuvxBCEHPT] [+ o option-name] [argument…] 설정

옵션이나 인수가 제공되지 않으면 set은 현재 로케일에 따라 모든 쉘 변수와 함수의 이름과 값을 현재 설정된 변수를 설정하거나 재설정하기위한 입력으로 재사용 할 수있는 형식으로 표시합니다. 읽기 전용 변수는 재설정 할 수 없습니다. POSIX 모드에서는 쉘 변수 만 나열됩니다.

옵션이 제공되면 쉘 속성을 설정하거나 설정 해제합니다. 지정된 경우 옵션의 의미는 다음과 같습니다.

-a 작성 또는 수정 된 각 변수 또는 함수에는 내보내기 속성이 제공되고 후속 명령 환경으로 내보내기 위해 표시됩니다.

그리고 이것도 :

'-'대신 '+'를 사용하면 이러한 옵션이 해제됩니다. 쉘을 호출 할 때 옵션을 사용할 수도 있습니다. 현재 옵션 세트는 $-에 있습니다.


SAVE=$(set +o) && set -o allexport && . .env; eval "$SAVE"

원래 옵션이 무엇이든 관계없이 저장 / 복원합니다.

를 사용 set -o allexport하면 정규 표현식없이 주석을 올바르게 건너 뛸 수 있다는 이점이 있습니다.

set +o자체적으로 모든 현재 옵션을 bash가 나중에 실행할 수있는 형식으로 출력합니다. 또한 편리합니다. set -o모든 현재 옵션을 인간 친화적 인 형식으로 출력합니다.


Silas Paul의 답변 개선

서브 쉘에서 변수를 내 보내면 변수가 명령에 로컬이됩니다.

(export $(cat .env | xargs) && rails c)


더 간단하게 :

  1. 파일의 내용을 잡아
  2. 빈 줄을 제거하십시오 (물건을 분리 한 경우를 대비하여)
  3. 주석을 제거하십시오 (일부 추가 한 경우 ...)
  4. export모든 줄에 추가
  5. eval 모든 일

eval $(cat .env | sed -e /^$/d -e /^#/d -e 's/^/export /')

다른 옵션 ( eval@Jaydeep 덕분에 실행할 필요가 없음 ) :

export $(cat .env | sed -e /^$/d -e /^#/d | xargs)

마지막으로 인생을 정말 쉽게 만들고 싶다면 이것을 다음에 추가하십시오 ~/.bash_profile.

function source_envfile() { export $(cat $1 | sed -e /^$/d -e /^#/d | xargs); }

(BASH 설정을 다시로드하십시오! source ~/.bash_profile또는 새 탭 / 창을 만들고 문제를 해결하십시오). 다음과 같이 호출하십시오.source_envfile .env


내가 찾은 가장 짧은 방법 :

귀하의 .env파일 :

VARIABLE_NAME="A_VALUE"

그런 다음

. ./.env && echo ${VARIABLE_NAME}

보너스 : 짧은 1 라이너이기 때문에 package.json파일에 매우 유용 합니다

  "scripts": {
    "echo:variable": ". ./.env && echo ${VARIABLE_NAME}"
  }

원래 스크립트를 사용하여 변수를 설정할 수 있지만 독립형 도트를 사용하여 다음과 같이 호출해야합니다.

. ./minientrega.sh

또한 cat | while read접근 방식에 문제가있을 수 있습니다 . 나는 접근 방식을 사용하는 것이 좋습니다 while read line; do .... done < $FILE.

다음은 실제 예입니다.

> cat test.conf
VARIABLE_TMP1=some_value

> cat run_test.sh
#/bin/bash
while read line; do export "$line";
done < test.conf
echo "done"

> . ./run_test.sh
done

> echo $VARIABLE_TMP1
some_value

다른 답변을 바탕으로 PREFIX_ONE="a word"다음 과 같이 공백이있는 값을 포함하여 파일의 행 하위 집합 만 내보내는 방법이 있습니다 .

set -a
. <(grep '^[ ]*PREFIX_' conf-file)
set +a

이전에 제안한 솔루션에 문제가 있습니다.

  • @anubhava의 솔루션은 bash 친화적 인 구성 파일 작성을 매우 성가 시게하며 항상 구성을 내보내고 싶지 않을 수도 있습니다.
  • @Silas Paul 솔루션은 따옴표로 묶은 값에서 잘 작동하는 공백이나 다른 문자가있는 변수가 있으면 $()엉망이됩니다.

여기 내 솔루션은 여전히 ​​끔찍한 IMO이며 Silas가 해결 한 "한 아이에게만 내보내기"문제를 해결하지 못합니다 (범위를 제한하기 위해 하위 셸에서 실행할 수는 있음).

source .conf-file
export $(cut -d= -f1 < .conf-file)

먼저 아래와 같은 환경의 모든 키-값 쌍을 갖는 환경 파일을 만들고 내 경우에 원하는 이름을 지정하십시오. env_var.env

MINIENTREGA_FECHALIMITE="2011-03-31"
MINIENTREGA_FICHEROS="informe.txt programa.c"
MINIENTREGA_DESTINO="./destino/entrega-prac1"

그런 다음 아래와 같이 파이썬 환경의 모든 환경 변수를 내보내는 스크립트를 만들고 이름을 export_env.sh

#!/usr/bin/env bash

ENV_FILE="$1"
CMD=${@:2}

set -o allexport
source $ENV_FILE
set +o allexport

$CMD

이 스크립트는 첫 번째 인수를 환경 파일로 사용하여 해당 파일의 모든 환경 변수를 내 보낸 다음 그 후에 명령을 실행합니다.

용법:

./export_env.sh env_var.env python app.py

값의 공백

여기에는 많은 훌륭한 답변이 있지만 값에 공백이 지원되지 않는 것으로 나타났습니다.

DATABASE_CLIENT_HOST=host db-name db-user 0.0.0.0/0 md5

빈 줄과 주석을 지원하여 이러한 값으로 작동하는 2 가지 솔루션을 찾았습니다.

하나는 sed 및 @ javier-buzzi 답변을 기반으로합니다 .

source <(sed -e /^$/d -e /^#/d -e 's/.*/declare -x "&"/g' .env)

그리고 @ john1024 답변을 기반으로 루프에 읽기 줄이있는 하나

while read -r line; do declare -x "$line"; done < <(egrep -v "(^#|^\s|^$)" .env)

여기서 핵심은 declare -x큰 따옴표로 줄을 사용 하고 넣는 것입니다. 왜 그런지 모르겠지만 루프 코드를 여러 줄로 다시 포맷하면 작동하지 않습니다. 나는 bash 프로그래머가 아니며 함께 모여서 여전히 마술입니다 :)


내 요구 사항은 다음과 같습니다.

  • export접두사가 없는 간단한 .env 파일 (dotenv와의 호환성을 위해)
  • 따옴표로 묶는 값 지원 : TEXT = "alpha bravo charlie"
  • 접두사 #과 빈 줄 지원
  • mac / BSD와 linux / GNU 모두에 보편적

위의 답변에서 컴파일 된 전체 작업 버전 :

  set -o allexport
  eval $(grep -v '^#' .env | sed 's/^/export /')
  set +o allexport

.envMac에서 docker-compose 및 파일로 작업하고 .env테스트를 위해 내 bash 셸로 가져오고 싶었 습니다. 여기에서 "최상의"답변은 다음 변수에서 넘어졌습니다.

.env

NODE_ARGS=--expose-gc --max_old_space_size=2048

해결책

그래서 나는을 사용 eval하고 env var defs를 작은 따옴표로 묶었습니다.

eval $(grep -v -e '^#' .env | xargs -I {} echo export \'{}\')

배쉬 버전

$ /bin/bash --version
GNU bash, version 3.2.57(1)-release (x86_64-apple-darwin18)
Copyright (C) 2007 Free Software Foundation, Inc.

변수 중 하나에 공백이 포함 된 값이 포함되어 오류가 발생하는 경우 bash IFS(내부 필드 구분 기호)를 재설정하여 bash가 결과를 실행 파일 의 매개 변수 목록으로 \n해석 하도록 할 수 cat .env있습니다 env.

예:

IFS=$'\n'; env $(cat .env) rails c

또한보십시오:


--env-file쉘에서 Docker를 재사용하려고 할 때이 스레드를 발견했습니다 . 형식 은 bash와 호환되지 않지만 간단합니다 : name=value, 따옴표 없음, 대체 없음. 또한 빈 줄과 #주석은 무시 합니다.

나는 posix 호환을 얻지 못했지만 bash와 같은 쉘에서 작동 해야하는 것이 있습니다 (OSX 10.12.5의 zsh 및 Ubuntu 14.04의 bash에서 테스트 됨).

while read -r l; do export "$(sed 's/=.*$//' <<<$l)"="$(sed -E 's/^[^=]+=//' <<<$l)"; done < <(grep -E -v '^\s*(#|$)' your-env-file)

그것은 하지 않습니다 위에 링크 된 문서의 예를 세 가지 경우를 처리 :

  • bash: export: `123qwe=bar': not a valid identifier
  • bash: export: `org.spring.config=something': not a valid identifier
  • 통과 구문을 처리하지 않습니다 (bare FOO)

내 .env :

#!/bin/bash
set -a # export all variables

#comments as usual, this is a bash script
USER=foo
PASS=bar

set +a #stop exporting variables

호출 :

source .env; echo $USER; echo $PASS

참조 https://unix.stackexchange.com/questions/79068/how-to-export-variables-that-are-set-all-at-once

참고 URL : https://stackoverflow.com/questions/19331497/set-environment-variables-from-file-of-key-value-pairs



반응형