How to add a directory to your PATH

Julia Evans

PATH에 디렉터리를 추가하는 방법

오늘 친구와 PATH에 디렉터리를 추가하는 방법에 대해 이야기했어요. 오랫동안 터미널을 써 와서 저에게는 당연하게 느껴지는 일인데, 막상 방법을 검색해 보니 모든 과정을 다 설명해 주는 자료를 찾기가 어렵더라고요. 대부분 “이걸 ~/.bashrc에 추가하세요”라고만 하는데, bash를 쓰지 않는다면 어떻게 해야 할까요? bash 설정 파일이 다른 곳에 있다면요? 그리고 애초에 어떤 디렉터리를 추가해야 하는지는 어떻게 알아내야 할까요?

그래서 좀 더 완전한 설명을 정리해 보고, 그동안 겪었던 함정들도 함께 적어 보려고 해요.

1단계: 어떤 셸을 사용하고 있나요?

자신이 어떤 셸을 쓰고 있는지 모르겠다면, 이렇게 확인해 볼 수 있어요. 다음 명령어를 실행해 보세요:

ps -p $$ -o pid,comm=
  • bash를 사용 중이라면 97295 bash처럼 출력돼요
  • zsh를 사용 중이라면 97295 zsh처럼 출력돼요
  • fish를 사용 중이라면 “In fish, please use $fish_pid” 같은 오류가 출력돼요 ($$는 fish에서는 유효한 문법이 아니지만, 어쨌든 오류 메시지를 보면 fish를 쓰고 있다는 걸 알 수 있어요. 아마 이미 알고 계셨겠지만요)

참고로 bash는 Linux의 기본 셸이고, zsh는 Mac OS의 기본 셸이에요(2024년 기준). 이 글에서는 bash, zsh, fish 세 가지만 다룰게요.

2단계: 셸 설정 파일 찾기

  • zsh라면 아마 ~/.zshrc예요
  • bash라면 ~/.bashrc일 수도 있지만, 좀 복잡해요. 다음 섹션의 설명을 참고해 주세요
  • fish라면 아마 ~/.config/fish/config.fish예요 (100% 확실하게 확인하고 싶다면 echo $__fish_config_dir을 실행해 보세요)

bash 설정 파일에 대한 참고 사항

bash에는 세 가지 설정 파일이 있을 수 있어요: ~/.bashrc, ~/.bash_profile, ~/.profile이요.

시스템에서 어느 파일을 사용하도록 설정되어 있는지 잘 모르겠다면, 이렇게 테스트해 보는 걸 추천해요:

  1. ~/.bashrcecho hi there를 추가하세요
  2. 터미널을 다시 시작하세요
  3. “hi there”가 보인다면 ~/.bashrc가 사용되고 있다는 뜻이에요! 성공이에요!
  4. 그렇지 않다면 해당 줄을 지우고 ~/.bash_profile에서 같은 방법으로 시도해 보세요
  5. 앞의 두 파일로도 안 된다면 ~/.profile도 시도해 볼 수 있어요.

(bash가 어떤 설정 파일을 사용할지 설명하는 복잡한 흐름도가 많이 있지만, 제 생각에는 그런 걸 외울 필요는 없고 그냥 직접 테스트해 보는 게 가장 빠른 방법이에요)

3단계: 어떤 디렉터리를 추가할지 알아내기

예를 들어 http-server라는 프로그램을 설치해서 실행하려는데 이렇게 동작하지 않는다고 해 볼게요:

$ npm install -g http-server
$ http-server
bash: http-server: command not found

http-server가 어떤 디렉터리에 있는지 어떻게 찾을 수 있을까요? 사실 일반적으로 이건 그리 간단하지 않아요. 답이 “npm이 어떻게 설정되어 있느냐에 달렸다” 같은 경우가 많거든요. 몇 가지 아이디어를 적어 볼게요:

  • 새로운 인스톨러(예: cargo, npm, homebrew 등)를 처음 설정할 때 PATH를 어떻게 업데이트하라는 안내가 출력되는 경우가 많아요. 그래서 그때 잘 봐 두면 안내를 얻을 수 있어요.
  • 가끔은 인스톨러가 셸 설정 파일을 자동으로 업데이트해서 PATH를 알아서 바꿔 주기도 해요
  • 그냥 “where does npm install things?”라고 구글링하면 답을 찾을 수 있을 때도 있어요
  • 일부 도구는 어디에 설치하도록 설정되어 있는지 알려 주는 하위 명령을 제공해요. 예를 들면:
    • Node/npm: npm config get prefix (뒤에 /bin/을 붙이세요)
    • Go: go env GOPATH (뒤에 /bin/을 붙이세요)
    • asdf: asdf info | grep ASDF_DIR (뒤에 /bin//shims/를 붙이세요)

3.1단계: 올바른 디렉터리인지 다시 확인하기

맞는 것 같은 디렉터리를 찾았다면, 실제로 올바른지 확인해 보세요! 예를 들어 제 컴퓨터에서는 http-server~/.npm-global/bin에 있더라고요. 그 디렉터리에서 직접 http-server를 실행해 보면 올바른 디렉터리인지 확인할 수 있어요. 이렇게요:

$ ~/.npm-global/bin/http-server
Starting up http-server, serving ./public

실행됐네요! 이제 PATH에 추가해야 할 디렉터리를 알았으니 다음 단계로 넘어가 볼게요!

4단계: 셸 설정 파일 수정하기

이제 필요한 두 가지 핵심 정보를 모두 알게 됐어요:

  1. PATH에 추가하려는 디렉터리는 무엇인지 (예: ~/.npm-global/bin/)
  2. 셸 설정 파일은 어디에 있는지 (예: ~/.bashrc, ~/.zshrc 또는 ~/.config/fish/config.fish)

이제 셸에 따라 추가해야 할 내용이 달라져요:

bash 설정 방법:

셸 설정 파일을 열고, 다음과 같은 줄을 추가하세요:

export PATH=$PATH:~/.npm-global/bin/

(당연히 ~/.npm-global/bin 부분은 실제로 추가하려는 디렉터리로 바꿔 주세요)

zsh 설정 방법:

bash와 똑같이 해도 되지만, zsh에서는 원한다면 조금 더 세련된 문법을 쓸 수도 있어요:

path=(
  $path
  ~/.npm-global/bin
)

fish 설정 방법:

fish에서는 문법이 달라요:

set PATH $PATH ~/.npm-global/bin

(fish에서는 fish_add_path를 쓸 수도 있어요. 이에 대한 설명은 아래쪽에 적어 두었어요)

5단계: 셸 다시 시작하기

이제 아주 중요한 단계예요: 셸 설정 파일을 업데이트해도 셸을 다시 시작하지 않으면 적용되지 않아요!

두 가지 방법이 있어요:

  1. 새 터미널(또는 터미널 탭)을 열고, 헷갈리지 않도록 기존 터미널은 닫는 것도 좋아요
  2. bash를 실행해서 새 셸을 시작하세요 (zsh를 쓰고 있다면 zsh, fish를 쓰고 있다면 fish를 실행하세요)

저는 두 방법 다 보통 잘 동작하더라고요.

이제 끝났을 거예요! 실행하려던 프로그램을 다시 실행해 보세요. 아마 잘 동작할 거예요.

만약 여전히 안 된다면, 다음과 같은 문제들을 겪고 있을 수도 있어요:

문제 1: 잘못된 프로그램이 실행된 경우

프로그램의 잘못된 버전이 실행되고 있다면, 디렉터리를 PATH의 끝이 아니라 앞부분에 추가해야 할 수도 있어요.

예를 들어 제 시스템에는 python3가 두 버전 설치되어 있는데, which -a를 실행하면 확인할 수 있어요:

$ which -a python3
/usr/bin/python3
/opt/homebrew/bin/python3

셸이 실제로 사용하는 건 목록에서 첫 번째로 나온 것이에요.

Homebrew 버전을 쓰고 싶다면 해당 디렉터리(/opt/homebrew/bin)를 PATH의 앞부분에 추가해야 해요. 셸 설정 파일에 이렇게 적으면 돼요 (평소처럼 $PATH:/opt/homebrew/bin/이 아니라 /opt/homebrew/bin/:$PATH예요)

export PATH=/opt/homebrew/bin/:$PATH

또는 fish에서는:

set PATH ~/.cargo/bin $PATH

문제 2: 프로그램이 셸에서 실행되지 않는 경우

지금까지의 설명은 프로그램을 셸에서 실행할 때만 적용돼요. IDE나 GUI에서, cron 작업에서, 혹은 다른 방식으로 프로그램을 실행하고 있다면 PATH에 디렉터리를 추가하는 방법이 달라질 수 있고, 구체적인 방법은 상황에 따라 달라져요.

cron 작업에서

몇 가지 방법은 다음과 같아요:

  • 실행하려는 프로그램의 전체 경로를 사용하기 (예: /home/bork/bin/my-program)
  • crontab 첫 줄에 원하는 전체 PATH를 적기 (예: PATH=/bin:/usr/bin:/usr/local/bin:… 같은 형태). 현재 셸에서 사용 중인 전체 PATH는 echo "PATH=$PATH"를 실행하면 확인할 수 있어요.

IDE/GUI에서는 어떻게 해야 하는지 솔직히 잘 모르겠어요. 오랫동안 그런 상황을 겪은 적이 없거든요. 누가 올바른 방법을 알려 주면 여기에 추가할게요.

문제 3: 중복된 PATH 항목 때문에 디버깅이 어려워지는 경우

PATH를 수정한 뒤 bash(또는 zsh, fish)를 실행해서 새 셸을 시작하면, 셸이 시작될 때마다 PATH에 계속 새로운 항목을 추가하기 때문에 중복된 PATH 항목이 생기는 경우가 많아요.

개인적으로 이런 중복 때문에 뭔가 고장 났던 적은 없는 것 같아요. 하지만 중복이 있으면 PATH 내용을 파악하려고 할 때 디버깅이 더 어려워질 수 있어요.

이렇게 대처할 수 있어요:

  1. PATH를 디버깅할 때는 새 터미널을 열어서 하세요. 그러면 “깨끗한” 상태에서 시작할 수 있어서 중복을 피할 수 있어요.
  2. 셸 설정 파일 마지막에서 PATH 중복을 제거하세요 (예를 들어 zsh에서는 typeset -U path로 할 수 있다고 해요)
  3. 디렉터리를 추가할 때 이미 PATH에 있는지 확인하세요 (예를 들어 fish에서는 fish_add_path --path /some/directory로 할 수 있는 걸로 알고 있어요)

PATH 중복을 제거하는 방법은 셸마다 다르고, 항상 내장된 방법이 있는 건 아니니 사용하는 셸에서 어떻게 하는지 찾아봐야 해요.

문제 4: PATH를 업데이트한 뒤 히스토리가 사라지는 경우

bash나 zsh에서 쉽게 겪을 수 있는 상황이에요:

  1. 명령어를 실행해요 (실패해요)
  2. PATH를 업데이트해요
  3. bash를 실행해서 설정을 다시 불러와요
  4. 위쪽 화살표를 몇 번 눌러 실패했던 명령어를 다시 실행해요 (또는 새 터미널을 열어요)
  5. 실패했던 명령어가 히스토리에 없어요! 왜 그럴까요?

이런 일이 생기는 이유는 bash에서 기본적으로 셸을 종료할 때까지 히스토리가 저장되지 않기 때문이에요.

해결 방법은 다음과 같아요:

  • 설정을 다시 불러오기 위해 bash를 실행하는 대신 source ~/.bashrc(zsh라면 source ~/.zshrc)를 실행하세요. 이렇게 하면 현재 세션 안에서 설정이 다시 불러와져요.
  • 셸이 종료될 때만 히스토리를 저장하는 대신 계속 저장하도록 설정하세요. (방법은 bash를 쓰는지 zsh를 쓰는지에 따라 달라요. zsh의 히스토리 옵션은 좀 복잡해서 정확히 어떤 방법이 가장 좋은지는 저도 잘 모르겠어요)

source에 대한 참고 사항

cargo(Rust 인스톨러)를 처음 설치하면 PATH 설정 방법에 대해 이런 안내가 나오는데, 특정 디렉터리를 전혀 언급하지 않아요.

This is usually done by running one of the following (note the leading DOT):

. "$HOME/.cargo/env"        	# For sh/bash/zsh/ash/dash/pdksh
source "$HOME/.cargo/env.fish"  # For fish

의도는 그 줄을 셸 설정 파일에 추가하면, 해당 스크립트가 자동으로 PATH(그리고 다른 것들도) 설정해 준다는 거예요.

이런 방식은 꽤 흔해요 (예를 들어 Homebrewbrew shellenv를 eval하라고 제안해요). 두 가지 접근 방법이 있어요:

  1. 그냥 도구가 제안하는 대로 하는 거예요 (예: . "$HOME/.cargo/env"를 셸 설정 파일에 추가하기)
  2. 그 스크립트가 PATH에 어떤 디렉터리를 추가하는지 알아내서 직접 추가하는 거예요. 제가 한다면 이렇게 할 거예요:
    • 셸에서 . "$HOME/.cargo/env"를 실행해요 (fish를 쓴다면 fish용 버전을 실행해요)
    • echo "$PATH" | tr ':' '\n' | grep cargo를 실행해서 어떤 디렉터리가 추가됐는지 확인해요
    • /Users/bork/.cargo/bin이라고 나오는 걸 확인하고 이를 ~/.cargo/bin으로 줄여요
    • ~/.cargo/bin 디렉터리를 PATH에 추가해요 (이 글의 설명대로)

도구가 제안하는 대로 하는 게 잘못됐다고 생각하지는 않아요 (그게 “가장 좋은 방법”일 수도 있어요!). 하지만 저는 개인적으로 정확히 어떤 설정을 바꾸는지 알고 싶어서 보통 두 번째 방법을 사용해요.

fish_add_path에 대한 참고 사항

fish에는 PATH에 디렉터리를 추가할 때 쓸 수 있는 fish_add_path라는 편리한 함수가 있어요. 이렇게 실행하면 돼요:

fish_add_path /some/directory

이건 정말 멋져요 (명령어가 정말 간단하잖아요!) 하지만 저는 몇 가지 이유로 더 이상 사용하지 않아요:

  1. 가끔 fish_add_path는 앞으로의 모든 세션에 대해 PATH를 업데이트하고(“universal variable”로), 가끔은 현재 세션에 대해서만 PATH를 업데이트하는데, 어느 쪽이 적용될지 구분하기가 어렵더라고요. 이론상으로는 문서에 설명이 되어 있지만 저는 이해하지 못했어요.
  2. 만약 몇 주나 몇 달 뒤에 실수 때문에 PATH에서 해당 디렉터리를 제거해야 할 일이 생기면, 그게 좀 어렵더라고요 (그래도 이 GitHub 이슈의 댓글에 설명이 있긴 해요).

마무리

이 글이 도움이 되었으면 좋겠어요. PATH에 디렉터리를 추가할 때 겪었던 다른 큰 함정이 있거나, 이 글에 대해 질문이 있다면 (Mastodon이나 Bluesky에서) 알려 주세요!

원문은 Julia Evans님이 에 게재했습니다.

이 글은 muse-spark-1.2-contributor 모델을 사용해 번역했습니다.