Linux / 명령어 / dirname - 경로에서 디렉터리 부분 추출
dirname은 경로 문자열에서 마지막 파일명이나 디렉터리 이름을 제거하고 그 앞의 디렉터리 부분을 출력하는 명령입니다. 셸 스크립트에서 파일의 상위 경로를 구하거나 basename과 함께 경로를 나누어 처리할 때 유용합니다.
dirname은 실제 파일 시스템을 탐색하거나 상위 디렉터리의 존재를 확인하지 않습니다. 입력 문자열에 정해진 규칙을 적용하므로, 실제 절대 경로나 심볼릭 링크 해석이 필요하면 realpath 같은 명령을 사용해야 합니다.
dirname 명령어란?
전체 경로에서 마지막 구성 요소를 제외한 부분을 얻으려면 다음과 같이 실행합니다.
dirname /home/user/report.txt
출력은 다음과 같습니다.
/home/user
입력한 마지막 이름이 실제 파일인지 디렉터리인지는 확인하지 않습니다. 단순한 문자열 처리이므로 존재하지 않는 경로에도 같은 규칙이 적용됩니다.
기본 문법과 사용법
dirname 이름 ...
GNU dirname은 여러 경로를 받아 각각의 결과를 한 줄씩 출력할 수 있습니다.
dirname /var/log/nginx/access.log dirname /home/user/Documents/ dirname relative/path/file.txt
일반적인 결과는 각각 /var/log/nginx, /home/user, relative/path입니다. 끝의 슬래시와 연속된 슬래시는 정리 과정에서 달라질 수 있으므로 원래 문자열을 그대로 보존하는 용도로 사용하지 마세요.
입력 형태별 결과
| 입력 | 일반적인 출력 |
|---|---|
/home/user/report.txt |
/home/user |
docs/manual.pdf |
docs |
notes.txt |
. |
/usr/ |
/ |
/ |
/ |
슬래시가 없는 이름
입력에 슬래시가 없으면 현재 디렉터리를 뜻하는 점 하나를 출력합니다.
dirname report.txt
.
이 결과는 report.txt라는 파일이 실제 현재 디렉터리에 있다는 뜻이 아니라, 입력 문자열에서 디렉터리 부분을 표현한 것입니다.
절대 경로와 루트 경로
절대 경로의 마지막 구성 요소를 제거해 루트만 남으면 /를 출력합니다.
dirname /etc dirname /
두 명령 모두 일반적으로 /를 출력합니다. 루트의 부모를 문자열로 표현해도 루트 자체입니다.
경로 끝의 슬래시
마지막의 불필요한 슬래시는 먼저 제거된 뒤 마지막 구성 요소가 처리됩니다.
dirname /srv/www/site/ dirname /srv/www/site///
두 입력 모두 일반적으로 /srv/www를 출력합니다. 원본의 슬래시 개수나 끝 슬래시를 보존해야 하는 작업에는 적합하지 않습니다.
여러 경로 처리하기
여러 이름을 한 번에 지정하기
GNU 구현에서는 여러 경로를 나열할 수 있습니다.
dirname /srv/www/index.html /var/log/syslog /home/user/file.txt
각 입력에 대한 디렉터리 부분이 한 줄씩 출력됩니다.
/srv/www /var/log /home/user
-z로 NUL 문자 구분하기
파일명에 줄바꿈이 포함될 수 있는 자동화에서는 -z 또는 --zero로 결과 사이를 NUL 문자로 구분할 수 있습니다.
dirname -z /srv/www/index.html /var/log/syslog
이 옵션은 GNU 확장이므로 다른 Unix 계열 시스템에서도 실행해야 한다면 지원 여부를 확인하세요.
dirname과 basename 함께 사용하기
한 경로에서 디렉터리 부분과 마지막 이름을 각각 추출할 수 있습니다.
path='/home/user/docs/report.pdf' directory=$(dirname -- "$path") || exit 1 name=$(basename -- "$path") || exit 1 printf '디렉터리: %s\n' "$directory" printf '이름: %s\n' "$name"
출력은 다음과 같은 형태입니다.
디렉터리: /home/user/docs 이름: report.pdf
두 명령은 원본 문자열을 의미 있는 두 부분으로 나누는 데 편리하지만, 결과를 다시 합쳤을 때 원본의 중복 슬래시나 끝 슬래시까지 복원되지는 않습니다.
셸 스크립트에서 활용하기
출력 파일의 상위 디렉터리 만들기
파일을 생성하기 전에 상위 디렉터리를 준비할 수 있습니다.
output='/srv/backups/daily/archive.tar.gz' output_dir=$(dirname -- "$output") || exit 1 mkdir -p -- "$output_dir"
입력 경로를 신뢰할 수 없는 경우에는 원하는 기준 디렉터리 밖으로 벗어나지 않는지 별도로 검증해야 합니다. dirname 자체는 접근 범위를 제한하지 않습니다.
POSIX 셸 매개변수 확장과 비교하기
단순한 입력이라면 셸 매개변수 확장으로 슬래시 뒤의 마지막 부분을 제거할 수 있습니다.
path='/srv/www/index.html'
directory=${path%/*}
printf '%s\n' "$directory"
하지만 슬래시가 없는 이름, 루트 경로, 끝에 슬래시가 있는 경로에서는 dirname과 결과가 달라질 수 있습니다. 입력 형태가 다양하다면 직접 만든 확장식의 예외를 충분히 시험하세요.
dirname, realpath와 pwd의 차이
| 명령 | 처리 대상 | 주요 결과 |
|---|---|---|
dirname |
입력한 경로 문자열 | 마지막 이름을 제외한 문자열 |
basename |
입력한 경로 문자열 | 마지막 파일명 또는 디렉터리 이름 |
realpath |
지정한 경로와 파일 시스템 | 정규화되거나 심볼릭 링크가 해석된 경로 |
pwd |
현재 프로세스의 작업 위치 | 현재 작업 디렉터리의 절대 경로 |
dirname ../logs/app.log는 문자열 기준으로 ../logs를 출력합니다. 이를 현재 위치 기준의 절대 경로로 바꾸거나 심볼릭 링크를 해석하지는 않습니다.
주요 옵션 정리
| 옵션 | 설명 |
|---|---|
-z, --zero |
각 결과를 줄바꿈이 아닌 NUL 문자로 끝냅니다. |
--help |
사용법과 지원 옵션을 출력합니다. |
--version |
설치된 GNU Coreutils 버전을 출력합니다. |
-- |
이후 인수를 옵션이 아닌 이름으로 처리합니다. |
자주 발생하는 문제
결과가 점 하나로 출력됨
입력 이름에 슬래시가 없기 때문입니다. dirname file.txt의 결과인 .은 문자열 관점에서 현재 디렉터리를 나타냅니다.
상위 디렉터리가 실제로 존재하지 않음
dirname은 파일 시스템을 검사하지 않습니다. 출력된 디렉터리를 실제로 사용하려면 존재 여부와 접근 권한을 별도로 확인해야 합니다.
공백이나 와일드카드가 있는 경로가 깨짐
변수를 큰따옴표로 묶고 하이픈으로 시작할 수 있는 값 앞에는 --를 사용하세요.
dirname -- "$path"
FAQ
dirname은 실제 상위 디렉터리를 찾나요?
아닙니다. 입력한 경로 문자열에서 마지막 구성 요소를 제거할 뿐 실제 경로의 존재 여부나 심볼릭 링크를 검사하지 않습니다.
dirname file.txt가 점 하나를 출력하는 이유는 무엇인가요?
입력에 디렉터리를 구분하는 슬래시가 없기 때문에 현재 디렉터리를 나타내는 .을 출력합니다.
여러 경로를 한 번에 처리할 수 있나요?
GNU dirname은 여러 경로를 인수로 받아 각 결과를 출력합니다. 다른 Unix 구현과의 이식성이 필요하면 지원 형식을 먼저 확인하세요.
절대 경로가 필요하면 dirname을 사용해도 되나요?
dirname은 상대 경로를 절대 경로로 바꾸지 않습니다. 정규화된 절대 경로가 필요하면 목적에 맞는 realpath 옵션을 사용하세요.









