bashrc profile env 차이를 모를 때 생기는 환경변수 오류

조회수: 0

리눅스에서 개발을 하다 보면 분명히 PATH를 추가했는데 어떤 터미널에서는 잘 되고, cron이나 서비스에서는 명령을 못 찾는 경우가 자주 발생한다. 같은 서버인데 쉘에 따라, 접속 방식에 따라, 심지어 편집한 파일에 따라 동작이 달라져서 헷갈리기 쉽다.

이 문제의 출발점은 bashrc, profile, env 파일의 역할이 서로 다르다는 점을 정확히 이해하지 못한 데에 있다. 겉으로 보기에는 모두 환경변수를 설정하는 파일이지만 어느 시점에, 어떤 프로그램이, 어떤 방식으로 읽는지가 모두 다르다. 여기서 한 번만 꼬이면 재현하기 어려운 환경변수 오류가 반복된다.

아래에서는 세 파일의 위치와 역할, 언제 실행되는지, 어떤 설정을 어디에 넣어야 하는지, 그리고 잘못 설정했을 때 실제로 어떤 문제가 생기는지를 순서대로 살펴본다.

로그인 셸과 인터랙티브 셸 이해하기

bashrc와 profile 이야기를 하기 전에 로그인 셸과 인터랙티브 셸 개념을 간단히 정리해 두면 전체 구조가 훨씬 명확해진다.

로그인 셸은 사용자 계정으로 처음 접속할 때 시작되는 셸이다. ssh로 서버에 접속하거나 콘솔 로그인 화면에서 아이디와 비밀번호를 입력해 들어갈 때가 대표적이다.

인터랙티브 셸은 사용자가 직접 명령을 입력하는 셸을 뜻한다. 프롬프트가 보이고 명령을 하나씩 치는 일반적인 터미널이 여기에 해당한다. 로그인 셸이면서 인터랙티브일 수도 있고 비로그인 인터랙티브 셸일 수도 있다. 데스크탑 환경에서 터미널 앱을 띄웠을 때가 대표적인 비로그인 인터랙티브 셸이다.

bash는 이 두 상황에 따라 서로 다른 설정 파일을 읽는다. 이때 어느 파일이 언제 실행되는지 모르면 환경변수를 어디에 넣어야 할지 헷갈린다.

profile 계열 파일의 역할

profile 계열 파일은 로그인 셸이 시작될 때 한 번 실행되는 초기 설정 스크립트다. 전통적으로는 다음과 같은 파일들이 있다.

  • 시스템 전체 설정용
    • etc profile
  • 사용자별 설정용
    • 홈 디렉터리의 profile
    • bash를 사용할 때는 bash profile 또는 bash login

배포판마다 약간의 차이는 있지만 공통된 특징은 로그인 시점에 한 번 실행된다는 점이다. 그래서 다음과 같은 설정을 넣기에 적합하다.

  • PATH, LANG 등 기본 환경변수
  • 공통으로 필요한 툴의 경로 설정
  • 한번만 실행하면 되는 초기 스크립트

ssh 접속이나 콘솔 로그인처럼 로그인 셸이 시작될 때만 실행되므로, 데스크탑 환경에서 터미널 앱을 새로 열었을 때는 이 파일이 실행되지 않는 경우도 있다. 그 결과 PATH를 profile에만 넣어 두면 ssh로 접속했을 때는 잘 되는데, GUI 터미널에서는 명령을 못 찾는 상황이 발생할 수 있다.

bashrc 파일의 역할

bashrc는 인터랙티브 비로그인 셸에서 주로 사용되는 설정 파일이다. 홈 디렉터리의 bashrc가 대표적이다. 데스크탑 환경에서 터미널 앱을 열면 대부분 로그인 과정 없이 곧바로 bashrc가 실행된다.

bashrc에는 다음과 같은 설정을 넣는 것이 일반적이다.

  • 프롬프트 모양 설정
  • alias 정의 예를 들어 ll, la
  • 자주 쓰는 함수
  • 히스토리 관련 옵션

즉 사용자가 명령을 편하게 치도록 돕는 인터랙티브용 설정이 주 대상이다. 환경변수를 아예 넣지 말아야 하는 것은 아니지만, 로그인 여부에 따라 실행 파일이 달라질 수 있다는 점을 고려해야 한다.

실제로 많은 배포판에서는 profile에서 bashrc를 한 번 더 읽어 오도록 구성해 두는 경우가 많다. 이렇게 하면 로그인 셸에서도 bashrc 내용이 적용돼 설정이 두 번 나뉘는 문제를 어느 정도 줄일 수 있다.

env 파일의 역할과 오해

env라는 이름의 파일은 사실 표준이 있는 것은 아니다. 그러나 여러 도구에서 환경변수 설정용 파일 이름으로 널리 쓰이고 있다.

대표적인 예시는 다음과 같다.

  • 애플리케이션 루트의 env 또는 dotenv
  • 도커 이미지에서 환경변수 파일
  • 시스템의 env 디렉터리 아래에 개별 서비스용 env 파일

이 파일들은 보통 key value 쌍으로 환경변수를 정의해 두고, 애플리케이션이나 프로세스 관리자가 이를 읽어 환경을 구성한다. bash 자체가 자동으로 읽는 파일이 아니라는 점이 중요하다.

즉 env 파일에만 환경변수를 넣어 두고 쉘 설정과 제대로 연결하지 않으면 터미널에서는 값이 보이지 않고, 반대로 쉘에만 설정해 두면 서비스 프로세스나 배포 스크립트에서는 값이 비어 있는 상황이 발생한다.

자주 발생하는 환경변수 오류 사례

bashrc, profile, env의 역할을 혼동할 때 실무에서 자주 마주치는 오류 패턴을 몇 가지로 정리하면 다음과 같다.

첫째 cron과 시스템 서비스에서 PATH가 다르게 잡히는 문제다. 사용자는 홈 디렉터리 bashrc에만 PATH를 추가해 두었는데 cron은 비인터랙티브 비로그인 셸을 사용하기 때문에 해당 파일을 읽지 않는다. 결국 crontab에서 실행하는 스크립트가 명령을 찾지 못해 실패한다.

둘째 ssh로는 잘 되는데 데스크탑 터미널에서는 안 되는 문제다. profile에만 환경변수를 정의해 두고 데스크탑 터미널이 비로그인 셸로 실행될 때 profile을 읽지 않는 구성이라면, 두 환경에서 완전히 다른 결과가 나온다. 반대 상황도 마찬가지다.

셋째 애플리케이션 env 파일에만 설정해 두고 개발자가 직접 터미널에서 테스트할 때는 값이 비어 있어 예상과 다른 동작을 하는 경우다. 예를 들어 데이터베이스 접속 정보나 외부 API 키를 env 파일에만 설정해 두고, 로컬 쉘에서는 export를 하지 않았다면 수동 테스트에서 오류가 발생한다.

넷째 sudo를 사용할 때 환경변수가 사라지는 현상이다. 일반 사용자 계정의 bashrc 또는 profile에만 설정을 넣어 두었을 뿐 시스템 전체에는 적용하지 않았다면, sudo 명령 실행 시 환경이 달라져 PATH가 바뀌거나 특정 변수들이 빠질 수 있다.

어떤 설정을 어디에 넣을지 기준 세우기

실수를 줄이려면 각각의 파일을 어떤 기준으로 사용할지 팀 차원의 원칙을 세우는 편이 좋다. 예를 들어 다음과 같은 기준을 생각해 볼 수 있다.

  • 시스템 전체에 공통으로 필요한 환경변수는 etc profile 또는 etc profile d 아래에 스크립트 파일로 정의한다
  • 사용자 개인의 편의 설정은 홈 디렉터리 bashrc에 넣는다
  • 로그인 시 한 번만 필요한 설정이 있다면 홈 디렉터리 profile이나 bash profile에 넣는다
  • 애플리케이션 전용 환경변수는 프로젝트 루트의 env 파일에 정의하되 배포 스크립트나 서비스 설정에서 이를 읽어 export하도록 명확히 연결한다

이렇게 역할을 분리해 두면 나중에 문제가 발생했을 때 어느 파일을 먼저 확인해야 할지 바로 떠오른다.

안전하게 설정을 적용하고 검증하는 방법

환경변수 관련 설정을 수정했다면 바로 적용과 검증까지 이어서 하는 습관이 중요하다.

시나리오별로 다음과 같은 확인 절차를 추천할 수 있다.

  • 터미널에서 echo 명령으로 현재 환경변수 값을 확인한다
  • 새 터미널을 열어 동일한 값이 유지되는지 확인해 로그인 여부에 따른 차이를 체크한다
  • cron 잡이나 시스템 서비스 유닛에서 printenv 또는 env를 호출해 해당 환경에서 실제로 어떤 값이 보이는지 로그로 남긴다
  • sudo를 사용하는 명령이라면 sudo env를 통해 승격된 환경에서 변수 값이 유지되는지 점검한다

특히 cron과 서비스 환경은 인터랙티브 셸과 동작 방식이 다르므로, 별도의 검증을 반드시 거치는 편이 좋다.

정리와 마무리

bashrc, profile, env는 모두 환경과 관련된 파일이지만 읽히는 시점과 주 사용처가 분명히 다르다. 이 차이를 이해하지 못한 채 아무 파일에나 환경변수를 추가하다 보면 특정 상황에서만 재현되는 애매한 오류에 시달리게 된다.

핵심은 다음 세 가지다.

  • 로그인 셸과 인터랙티브 셸 개념을 구분한다
  • profile 계열은 로그인 시 한 번 실행되는 초기 환경 설정으로 보고, bashrc는 사용자의 인터랙티브 작업 편의를 위한 설정으로 사용한다
  • env 파일은 쉘이 아니라 애플리케이션이나 서비스가 읽는 별도의 설정이라는 점을 인식하고, 배포 스크립트나 서비스 정의와 연결해 관리한다

이 구조를 머릿속에 한 번만 확실히 그려 두면, 앞으로 환경변수 관련 오류를 디버깅할 때 어느 지점을 먼저 살펴봐야 할지 자연스럽게 떠오르게 되고, 설정을 설계할 때도 훨씬 일관성을 유지할 수 있다.