키 / 값 쌍 파일에서 환경 변수 설정
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 /')
다음은 sed
eval을 실행하지 않거나 루비가 필요한 다른 솔루션입니다.
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 prac1
minientrega.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)
더 간단하게 :
- 파일의 내용을 잡아
- 빈 줄을 제거하십시오 (물건을 분리 한 경우를 대비하여)
- 주석을 제거하십시오 (일부 추가 한 경우 ...)
export
모든 줄에 추가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
.env
Mac에서 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
'development' 카테고리의 다른 글
PostgreSQL 데이터베이스로 SQL 덤프 가져 오기 (0) | 2020.02.21 |
---|---|
단위 테스트를 수행 할 때 C # "내부"액세스 수정 자 (0) | 2020.02.21 |
"git reset"과 "git checkout"의 차이점은 무엇입니까? (0) | 2020.02.21 |
getApplication () 대 getApplicationContext () (0) | 2020.02.21 |
"ON UPDATE CASCADE"를 사용하는 경우 (0) | 2020.02.21 |