TL;DR

  • 단순한 KEY=VALUE 형식의 .env 파일은 export $(<.env)로 환경 변수에 내보낼 수 있지만, 공백·따옴표·특수 문자·주석이 있으면 제대로 처리되지 않음.
  • 변수 하나는 export FOO=bar로 설정할 수 있지만, 명령어에 비밀 값이 포함되면 셸 기록 파일에 평문으로 저장될 수 있음.
  • Bash에서 set -o allexport를 켠 뒤 .env 파일을 source하고 옵션을 끄면 파일의 변수를 자동으로 내보낼 수 있음.
  • allexport와 source를 함께 쓰면 ${RANDOM} 같은 셸 확장과 명령 실행을 이용한 동적 환경 변수 정의가 가능함.
  • 이 방식은 .env 파일을 Bash 스크립트로 실행하므로 단순한 KEY=VALUE 파일을 기대하는 도구와 호환되지 않을 수 있으며, 신뢰하는 파일만 불러와야 함.

터미널에서 환경 변수를 설정할 때의 문제

  • 개인 프로젝트나 업무 프로젝트에서 환경 변수가 필요한 경우가 많으며, Docker/Podman의 --env-file .env 옵션이나 여러 프로그래밍 언어의 dotenv 라이브러리를 통해 .env 파일을 자동으로 읽을 수 있음.
  • 터미널에서 일회성 명령을 실행할 때는 파일을 직접 파싱해야 함.
  • 변수 하나만 설정할 때는 export FOO=bar를 실행하면 되지만, 변수가 많아지면 번거로움.
  • export 명령은 셸 기록 파일에 저장되어 CTRL-R을 누르고 명령어 일부를 입력해 과거에 내보낸 변수를 찾을 수 있음. 하지만 비밀 값이 포함된 명령어가 셸 기록 파일이나 다른 파일에 평문으로 저장되는 문제도 있음.

간단한 .env 파일 불러오기

  • 간단한 .env 파일의 모든 환경 변수를 불러오는 방법은 export $(<.env)임.
  • 이 명령은 .env 파일의 모든 줄을 읽고, 각 단어를 export 명령에 전달함.
  • 예를 들어 파일에 CAT=Bob과 OTHERCAT=Dimitri가 있으면 $(<.env)가 CAT=Bob OTHERCAT=Dimitri를 만들고, 이 값이 export에 전달되어 두 변수가 내보내짐.
  • 이 방식은 일반적인 .env 파서가 아니며, 단순한 KEY=VALUE 줄에서만 작동함. 공백, 따옴표, 특수 문자, 주석이 있으면 명령이 깨질 수 있음.
  • CAT=Bob, OTHERCAT=Dimitri, # What about turtles?, TURTLE=Sabrina가 들어 있는 파일은 export CAT=Bob OTHERCAT=Dimitri # What about turtles? TURTLE=Sabrina처럼 처리됨.
  • 각 단어가 export에 개별 인수로 전달되므로 #와 turtles?는 유효한 식별자가 아니라는 오류가 발생함.
  • 그래도 TURTLE 변수는 내보내짐.

Bash에서 .env 파일을 source하기

  • Bash에서 .env 파일을 불러오는 다른 방법은 allexport 옵션을 켜고 파일을 source한 뒤 옵션을 끄는 것임.
  • 실행 순서는 set -o allexport, source .env, set +o allexport임.
  • 이후 allexport를 끄면 새로 만들거나 수정하는 변수가 자동으로 내보내지지 않으며, 기본 상태로 돌아감.
  • allexport와 source를 함께 쓰면 셸 확장을 사용하거나 명령을 실행해 동적 환경 변수를 정의할 수 있음. 예를 들어 ${RANDOM}으로 LUCKY_NUMBER를 설정하고, keepassxc-cli show -sa Password ~/.secrets/personal.kdbx '/AWS/groot-key'의 결과로 API_KEY를 설정할 수 있음.
  • 이 방식에서는 .env 파일이 단순한 데이터 파일보다 강력한 Bash 스크립트가 됨.
  • 단점은 스크립트가 된 파일이 export $(<.env) 방식과 호환되지 않으며, docker run --env-file .env 또는 dotenv() 함수처럼 단순한 KEY=VALUE 파일을 기대하는 도구가 잘못 동작하거나 완전히 중단될 수 있다는 점임.
  • 파일의 스크립트가 실행되므로 신뢰하는 파일만 source해야 함.
  • set -a는 set -o allexport의 축약형임.