본문 바로가기
TYLER SONGBlog
← Blog index
CS학습4 min read

cd: 셸의 현재 작업 디렉터리를 바꾸는 내장 명령

cd(change directory)는 셸 프로세스의 현재 작업 디렉터리(CWD)를 변경하는 셸 내장 명령이다. 외부 프로그램이 아니라 셸 자신의 상태를 바꾸기 때문에 내장 명령으로 구현된다. 절대 경로와 상대 경로, `~`, `-`, `..` 같은 표기를 이해하면 터미널 이동이 훨씬 빨라진다.

By 송민성

1. 개념

cd(change directory)는 셸의 현재 작업 디렉터리(CWD, Current Working Directory) 를 바꾸는 명령이다. 상대 경로를 해석할 때 기준이 되는 위치가 CWD다.

shell
pwd # 현재 위치 출력 cd /var/log # 절대 경로로 이동 pwd

경로는 두 가지로 나뉜다.

구분설명예
절대 경로(absolute path)루트 /부터 시작/etc/nginx
상대 경로(relative path)CWD 기준../logs, src/app

자주 쓰는 특수 표기는 다음과 같다.

표기의미
.현재 디렉터리
..부모 디렉터리
~현재 사용자의 홈 디렉터리
-직전 디렉터리 ($OLDPWD)
인자 없음홈 디렉터리로 이동

2. 왜 사용하는가

  • 파일 경로를 매번 길게 쓰지 않고, 작업 위치를 기준으로 짧은 상대 경로를 쓸 수 있다.
  • git, npm, make 같은 도구는 대개 CWD를 기준으로 동작한다. 프로젝트 루트로 이동한 뒤 실행하는 것이 기본 흐름이다.
  • 스크립트에서 작업 기준 위치를 명확히 지정할 수 있다.

3. 동작 원리

모든 프로세스는 자신만의 CWD를 가진다. 셸도 하나의 프로세스이며, cd는 내부적으로 chdir() 시스템 콜을 호출해 셸 프로세스의 CWD를 바꾼다.

왜 `cd`는 내장 명령(builtin)인가? 외부 프로그램(/bin/ls 같은 실행 파일)을 실행하면 셸은 fork()로 자식 프로세스를 만들고 그 안에서 프로그램을 실행한다. 자식 프로세스가 CWD를 바꿔도 부모(셸)의 CWD는 바뀌지 않는다. 그래서 cd가 외부 프로그램이라면 아무 효과가 없다. 셸 자신이 직접 chdir()를 호출해야 하므로 내장 명령이다.

shell
type cd # cd is a shell builtin

cd는 이동 후 환경 변수도 갱신한다.

  • PWD: 새 현재 디렉터리
  • OLDPWD: 이동 전 디렉터리 (cd -가 사용)

또한 심볼릭 링크(symbolic link)를 따라 이동할 때, 기본 동작(-L)은 링크 경로 그대로 PWD에 기록하고, -P 옵션은 링크를 풀어 실제 물리 경로를 기록한다.

4. 코드 예제

shell
#!/usr/bin/env bash set -e # 임시 디렉터리 구조 만들기 base="$(mktemp -d)" mkdir -p "$base/project/src" "$base/project/logs" cd "$base/project" # 절대 경로 이동 pwd cd src # 상대 경로 이동 pwd cd ../logs # 부모로 올라간 뒤 logs로 pwd cd - # 직전 디렉터리(src)로 복귀 cd # 홈으로 이동 pwd # 공백이 있는 경로는 따옴표로 감싼다 mkdir -p "$base/my docs" cd "$base/my docs" pwd # 서브셸에서 이동하면 바깥 셸의 CWD는 유지된다 cd "$base" ( cd project/src && pwd ) pwd # 심볼릭 링크: 논리 경로(-L) vs 물리 경로(-P) ln -s "$base/project" "$base/link" cd -L "$base/link" && pwd cd -P "$base/link" && pwd rm -rf "$base"

실행하면 서브셸 ( ... ) 안에서의 cd가 바깥 셸에 영향을 주지 않는 것을 확인할 수 있다. 서브셸도 별도 프로세스이기 때문이다.

5. 시간 복잡도 또는 성능 특성

cd는 경로를 구성하는 각 요소(컴포넌트)를 차례로 탐색(path lookup)하므로 비용은 대략 경로 깊이에 비례한다. 다만 커널의 디렉터리 엔트리 캐시(dentry cache) 덕분에 실사용에서는 체감할 수 없는 수준이다. 별도로 외우거나 최적화할 성능 수치는 없다.

6. 실무 사용 사례

  • 프로젝트 이동: cd ~/work/my-app && npm run dev
  • 로그 확인: cd /var/log && tail -f syslog (환경에 따라 로그 파일 이름은 다를 수 있다)
  • 스크립트에서 기준 위치 고정: 스크립트가 어느 위치에서 호출되든 자기 디렉터리를 기준으로 동작하게 한다.
shell
#!/usr/bin/env bash cd "$(dirname "$0")" || exit 1 pwd
  • 자주 가는 곳 단축: CDPATH 환경 변수에 탐색 기준 디렉터리를 등록하면, 어느 위치에서든 cd my-app처럼 짧게 이동할 수 있다.
shell
export CDPATH=".:$HOME/work" cd my-app # ./my-app 이 없으면 ~/work/my-app 을 찾는다
  • 임시 이동: pushd/popd는 디렉터리 스택(stack)으로 이동 이력을 관리한다. cd -는 직전 한 곳만 기억하지만 pushd는 여러 곳을 쌓을 수 있다. (bash, zsh 등에서 지원)

7. 주의할 점

  • 실패 처리: cd가 실패했는데도 다음 명령이 계속 실행되면 엉뚱한 위치에서 작업하게 된다. 특히 rm과 조합하면 위험하다.
shell
# 위험: cd 실패 시 현재 위치에서 삭제가 실행된다 cd build; rm -rf ./* # 안전: 성공했을 때만 실행 cd build && rm -rf ./*
  • 공백 포함 경로: 변수를 쓸 때는 cd "$dir"처럼 따옴표로 감싼다.
  • 권한: 디렉터리에 실행(x) 권한이 없으면 진입할 수 없다(Permission denied).
  • `cd`는 셸 상태를 바꾼다: 스크립트 안의 cd는 스크립트를 실행한 별도 프로세스에만 영향을 준다. 스크립트를 실행한 뒤 터미널의 위치가 그대로인 것은 정상이다. 현재 셸에서 이동시키려면 source script.sh로 실행해야 한다.
  • `cd ..`와 심볼릭 링크: 링크를 통해 들어온 경우 -L과 -P에 따라 ..의 결과가 다를 수 있다.

8. 핵심 정리

  • cd는 셸 프로세스의 CWD를 chdir() 시스템 콜로 바꾸는 셸 내장 명령이다.
  • 자식 프로세스는 부모의 CWD를 바꿀 수 없으므로 외부 프로그램으로는 구현할 수 없다.
  • ~(홈), -(직전 위치), ..(부모), 인자 없음(홈)을 익히면 이동이 빨라진다.
  • 스크립트에서는 cd dir && 명령 또는 cd dir || exit 1로 실패를 반드시 처리한다.
  • 경로에 공백이 있을 수 있으므로 변수는 "$dir"처럼 따옴표로 감싼다.