셸 설정 파일 총정리: .bashrc, .zshrc, .profile의 차이

셸 설정 파일 총정리: .bashrc, .zshrc, .profile의 차이

터미널 환경을 설정하다 보면 .bashrc에 넣으라는 곳도 있고, .bash_profile에 넣으라는 곳도 있고, .zshrc에 넣으라는 곳도 있습니다. 비슷비슷한 이름의 파일이 왜 이렇게 많은 건지, 도대체 어디에 뭘 넣어야 하는 건지 헷갈리죠.

사실 이 파일들은 각각 로드되는 시점이 다릅니다. 그래서 PATH 환경 변수를 설정하든, Oh My Zsh 플러그인을 추가하든, Starship 프롬프트를 초기화하든 적절한 파일에 넣어야 제대로 동작합니다.

이 글에서는 Bash와 Zsh의 설정 파일이 각각 언제 로드되는지, 어떤 파일에 무엇을 넣는 게 좋은지 정리해보겠습니다.

로그인 셸 vs 인터랙티브 셸

셸 설정 파일을 이해하려면 먼저 셸의 두 가지 모드를 알아야 합니다.

로그인 셸은 사용자가 시스템에 로그인할 때 시작되는 셸입니다. SSH로 서버에 접속하거나, macOS에서 터미널 앱을 처음 열 때 실행됩니다. 시스템에 “나 왔어”라고 알리는 첫 번째 셸이라고 생각하면 됩니다.

인터랙티브 셸은 사용자가 명령어를 직접 입력하는 셸입니다. 이미 터미널이 열려 있는 상태에서 bashzsh를 입력해서 새로 시작하는 셸이 여기 해당합니다. 스크립트를 실행할 때처럼 사용자 입력 없이 돌아가는 셸은 비인터랙티브 셸이고요.

하나의 셸이 두 가지 속성을 동시에 가질 수도 있습니다. macOS 터미널을 열면 로그인이면서 인터랙티브인 셸이 시작되고, 터미널에서 bash를 입력하면 비로그인이면서 인터랙티브인 셸이 시작됩니다.

왜 이 구분이 중요할까요? 셸이 시작될 때 읽는 설정 파일이 모드에 따라 달라지기 때문입니다.

Bash 설정 파일

Bash는 셸 모드에 따라 다른 파일을 읽습니다.

로그인 셸일 때 Bash는 다음 순서로 파일을 찾습니다.

  1. ~/.bash_profile
  2. ~/.bash_login
  3. ~/.profile

이 세 파일 중 가장 먼저 발견된 하나만 읽습니다. ~/.bash_profile이 있으면 나머지는 무시하고, 없으면 ~/.bash_login을 찾고, 그것도 없으면 ~/.profile을 읽는 식입니다.

인터랙티브(비로그인) 셸일 때~/.bashrc만 읽습니다.

여기서 중요한 점은 Bash 로그인 셸이 ~/.bashrc를 자동으로 읽지 않는다는 겁니다. 그래서 ~/.bashrc에 별칭(alias)이나 함수를 정의해놓았는데 새 터미널을 열면 안 먹히는 상황이 생길 수 있죠.

이 문제를 해결하는 전통적인 패턴이 있습니다. ~/.bash_profile에서 ~/.bashrc를 명시적으로 불러오는 겁니다.

~/.bash_profile
# 환경 변수 설정 (로그인 시 한 번만 실행)
export EDITOR="vim"
export LANG="ko_KR.UTF-8"

# .bashrc가 있으면 불러오기
if [ -f ~/.bashrc ]; then
    source ~/.bashrc
fi
~/.bashrc
# 별칭 (매 셸 세션마다 필요)
alias ll='ls -la'
alias gs='git status'

# 프롬프트 설정
PS1='\u@\h:\w\$ '

이렇게 하면 로그인 셸에서도 ~/.bashrc의 설정이 적용됩니다.

~/.profile은 Bash 이전부터 존재하던 Bourne Shell(sh)의 설정 파일인데요. Bash가 ~/.bash_profile을 찾지 못할 때 대신 읽습니다. Ubuntu 같은 일부 리눅스 배포판에서는 ~/.bash_profile 대신 ~/.profile을 기본으로 사용하기도 합니다.

Zsh 설정 파일

Zsh는 Bash보다 설정 파일이 더 세분화되어 있습니다. 로드 순서대로 보면 이렇습니다.

  1. ~/.zshenv — 모든 Zsh 셸에서 항상 로드 (스크립트 실행 시에도)
  2. ~/.zprofile — 로그인 셸에서만 로드
  3. ~/.zshrc — 인터랙티브 셸에서 로드
  4. ~/.zlogin — 로그인 셸에서, ~/.zshrc 다음에 로드
  5. ~/.zlogout — 로그인 셸 종료 시 로드

Bash와 다른 점은 Zsh 로그인 셸이 ~/.zprofile~/.zshrc둘 다 읽는다는 겁니다. Bash처럼 ~/.bash_profile에서 ~/.bashrc를 source하는 작업이 필요 없죠.

실제로 자주 쓰는 파일은 이 중 두 개입니다.

~/.zshenv는 모든 Zsh 인스턴스에서 로드되기 때문에 정말 어디서든 필요한 환경 변수만 넣습니다. 스크립트 실행 시에도 로드되므로 무거운 작업은 피해야 합니다.

~/.zshrc는 인터랙티브 셸에서 로드되는 메인 설정 파일입니다. 별칭, 함수, 프롬프트 설정, 플러그인 초기화 등 대부분의 설정이 여기 들어갑니다. macOS 터미널은 기본적으로 로그인 + 인터랙티브 셸이라서 ~/.zshrc에 넣으면 거의 모든 상황에서 동작합니다.

~/.zshrc
# PATH 설정
eval "$(/opt/homebrew/bin/brew shellenv)"
export PATH="$HOME/bin:$PATH"

# 별칭
alias ll='ls -la'
alias gs='git status'
alias gp='git push'

# 런타임 버전 매니저
eval "$(mise activate zsh)"

# 프롬프트 (Starship 사용 시)
eval "$(starship init zsh)"

~/.zprofile은 Bash의 ~/.bash_profile에 대응하는 파일인데요. 로그인 시에만 한 번 실행되어야 하는 설정을 넣습니다. Homebrew를 설치할 때 ~/.zprofileeval 구문을 추가하라고 안내하는 게 이 때문이죠. 다만 ~/.zshrc에 넣어도 macOS에서는 잘 동작하기 때문에 ~/.zshrc 하나로 관리하는 사람도 많습니다.

Bash vs Zsh 비교

두 셸의 설정 파일 로드 방식을 표로 정리하면 이렇습니다.

상황BashZsh
로그인 셸~/.bash_profile (하나만)~/.zshenv~/.zprofile~/.zshrc~/.zlogin
인터랙티브 셸~/.bashrc~/.zshenv~/.zshrc
스크립트 실행(없음)~/.zshenv

가장 큰 차이는 Bash 로그인 셸은 ~/.bashrc를 안 읽지만, Zsh 로그인 셸은 ~/.zshrc를 읽는다는 점입니다. 그래서 Bash에서는 “source ~/.bashrc” 패턴이 필수적이고, Zsh에서는 필요 없습니다.

macOS Catalina 이후로는 기본 셸이 Zsh이기 때문에 Mac 사용자라면 ~/.zshrc 하나만 신경 쓰면 되는 상황이 많습니다.

어디에 뭘 넣어야 할까

셸 설정 파일이 여러 개 있다 보니 어떤 설정을 어디에 넣어야 하는지 고민이 되는데요. 실무에서 통하는 간단한 원칙이 있습니다.

Zsh 사용자 (macOS 기본)라면 ~/.zshrc에 거의 모든 걸 넣으면 됩니다. PATH 환경 변수 설정, 별칭, 함수, 플러그인 초기화, 프롬프트 설정 전부요. macOS 터미널이 로그인 + 인터랙티브 셸을 열기 때문에 ~/.zshrc는 항상 로드됩니다.

Bash 사용자라면 ~/.bashrc에 설정을 넣고, ~/.bash_profile에서 source하는 패턴을 씁니다. 앞에서 본 것처럼요.

좀 더 세밀하게 나누고 싶다면 이런 기준을 쓸 수 있습니다.

환경 변수(export)는 로그인 시 한 번만 설정하면 자식 프로세스에 상속됩니다. 원칙적으로는 ~/.zprofile이나 ~/.bash_profile에 넣으면 중복 설정을 피할 수 있는데요. 실제로는 ~/.zshrc에 넣어도 문제가 생기는 경우가 드물어서 크게 신경 쓰지 않아도 됩니다.

별칭과 함수는 자식 프로세스에 상속되지 않기 때문에 매 인터랙티브 셸에서 설정해야 합니다. ~/.bashrc~/.zshrc에 넣어야 하고요. 프롬프트 설정도 마찬가지입니다. Starship이나 Oh My Zsh를 쓴다면 이미 ~/.zshrc에 초기화 코드를 넣고 계실 거예요.

source 명령어

설정 파일을 수정한 후에는 변경 사항을 현재 셸에 적용해야 합니다. 새 터미널을 여는 방법도 있지만, source 명령어(또는 줄여서 .)로 현재 셸에서 바로 적용할 수 있습니다.

source ~/.zshrc
# 동일한 동작
. ~/.zshrc

source는 파일을 읽어서 현재 셸 환경에서 실행합니다. 새 프로세스를 만들지 않기 때문에 파일에서 설정한 환경 변수, 별칭, 함수 등이 현재 셸에 바로 반영되는 거죠.

주의할 점은 source가 파일 전체를 다시 실행하기 때문에 PATH에 경로를 추가하는 코드가 있으면 중복으로 쌓일 수 있다는 겁니다. 터미널을 새로 여는 게 더 깔끔할 때도 있습니다.

설정 파일 로드 순서 확인하기

지금 내 셸이 어떤 설정 파일을 읽고 있는지 직접 확인해볼 수 있습니다. 각 설정 파일에 echo 문을 넣어보면 됩니다.

echo 'echo "zshenv loaded"' >> ~/.zshenv
echo 'echo "zprofile loaded"' >> ~/.zprofile
echo 'echo "zshrc loaded"' >> ~/.zshrc

새 터미널을 열면 어떤 파일이 어떤 순서로 로드되는지 눈으로 확인할 수 있습니다.

결과
zshenv loaded
zprofile loaded
zshrc loaded

확인이 끝나면 추가한 echo 줄은 지워주세요.

현재 셸이 로그인 셸인지 확인하려면 다음 명령어를 씁니다.

echo $0

결과가 -zsh처럼 앞에 하이픈(-)이 붙어 있으면 로그인 셸이고, zsh처럼 하이픈 없이 나오면 비로그인 셸입니다.

흔한 실수와 해결법

셸 설정 파일을 다루다 보면 빠지기 쉬운 함정이 몇 가지 있습니다.

가장 흔한 실수는 Bash에서 ~/.bashrc에만 설정을 넣고 ~/.bash_profile에서 source하지 않는 겁니다. 인터랙티브 셸에서는 잘 되는데 새 터미널을 열면 설정이 안 먹히는 증상이 나타납니다.

반대로 ~/.bash_profile에만 별칭을 넣는 실수도 있습니다. 이러면 셸 안에서 bash를 새로 실행했을 때 별칭이 사라지죠.

~/.zshenv에 무거운 초기화 코드를 넣는 것도 피해야 합니다. 이 파일은 스크립트 실행 시에도 로드되기 때문에 eval "$(mise activate zsh)" 같은 코드를 넣으면 단순한 셸 스크립트도 느려질 수 있습니다. 이런 코드는 ~/.zshrc에 넣는 게 맞습니다.

설정 파일 간 순서 충돌도 주의해야 합니다. ~/.zprofile에서 PATH를 설정했는데 ~/.zshrc에서 다시 덮어쓰면 의도한 순서가 엉킬 수 있습니다. 한 파일에서 관리하는 게 혼란을 줄여줍니다.

마치며

셸 설정 파일은 종류가 많아 보이지만, 핵심은 로그인 셸과 인터랙티브 셸의 차이를 이해하는 겁니다. Bash는 ~/.bash_profile + ~/.bashrc 조합을, Zsh는 ~/.zshrc 하나로 대부분 해결할 수 있습니다.

PATH 환경 변수를 설정하거나, Homebrew 경로를 등록하거나, Mise로 런타임 버전을 관리하거나, Oh My Zsh로 플러그인을 추가할 때 이 글이 “이걸 어디에 넣지?” 하는 고민을 줄여줬으면 좋겠습니다.

This work is licensed under CC BY 4.0 CC BY

개발자를 위한 뉴스레터

달레가 정리한 AI 개발 트렌드와 직접 만든 콘텐츠를 전해드립니다.

Discord