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 옵션을 사용하세요.

관련 글과 공식 문서

같은 카테고리의 다른 글
Linux 강좌 / 파일과 명령 찾기 - find, locate, which, whereis

Linux 강좌 / 파일과 명령 찾기 - find, locate, which, whereis

find와 locate로 파일을 찾고 which, whereis, type으로 명령의 위치와 해석 방식을 확인합니다. 실시간 검색과 색인 검색의 차이도 짚습니다.

Linux / 명령어 / ss - 열린 포트와 소켓 연결 상태 확인

Linux / 명령어 / ss - 열린 포트와 소켓 연결 상태 확인

Linux ss 명령어의 기능과 기본 문법을 설명합니다. 실제 사용 예제, 주요 옵션과 작업 전 확인할 점을 알아봅니다.

Linux / 디스크 관리 / 파티션, 포맷, 마운트

Linux / 디스크 관리 / 파티션, 포맷, 마운트

Linux에서 디스크를 관리할 때 필요한 파티션 생성, 파일 시스템 포맷, 마운트 방법을 정리했습니다.

Linux / 명령어 / zip - 여러 파일을 ZIP 아카이브로 묶기

Linux / 명령어 / zip - 여러 파일을 ZIP 아카이브로 묶기

Linux zip 명령어의 용도와 기본 문법을 알아봅니다. 파일 처리 예제, 주요 옵션과 원본 보존·덮어쓰기 주의점을 설명합니다.

Linux / 명령어 / stat - 파일 정보와 메타데이터 확인

Linux / 명령어 / stat - 파일 정보와 메타데이터 확인

Linux stat 명령어로 파일 크기, 권한, 소유자, inode와 타임스탬프를 확인하는 방법을 설명합니다. atime·mtime·ctime·Birth의 차이와 출력 형식, 파일 시스템 조회법도 정리합니다.

Linux / 명령어 / nmap - 허가된 호스트의 포트와 서비스 조사

Linux / 명령어 / nmap - 허가된 호스트의 포트와 서비스 조사

Linux nmap 명령어의 기능과 기본 문법을 설명합니다. 실제 사용 예제, 주요 옵션과 작업 전 확인할 점을 알아봅니다.

Linux / 명령어 / cd - 디렉터리 이동

Linux / 명령어 / cd - 디렉터리 이동

Linux cd 명령어로 절대·상대 경로, 홈과 이전 디렉터리로 이동하는 방법을 설명합니다. 심볼릭 링크 처리, CDPATH, 스크립트와 sudo cd의 한계 및 오류 해결법도 정리합니다.

Linux / 명령어 / getent - NSS 사용자·그룹·호스트 정보 조회

Linux / 명령어 / getent - NSS 사용자·그룹·호스트 정보 조회

Linux getent 명령어의 기본 문법과 실제 사용 예제를 설명합니다. 주요 옵션과 결과를 해석할 때 주의할 점을 확인할 수 있습니다.

Linux / 명령어 / cp - 파일과 디렉터리 복사

Linux / 명령어 / cp - 파일과 디렉터리 복사

Linux cp 명령어로 파일과 디렉터리를 복사하는 방법을 설명합니다. 덮어쓰기 제어, 속성 보존, 심볼릭 링크, 희소 파일과 안전한 복사 옵션을 함께 정리합니다.

Linux / 명령어 / man - 명령어 매뉴얼 확인

Linux / 명령어 / man - 명령어 매뉴얼 확인

man 명령어로 리눅스 매뉴얼을 읽고 검색하는 방법을 설명합니다. 매뉴얼 섹션, 화면 이동, 키워드 검색, 셸 내장 명령 확인과 문서가 없을 때의 해결 방법을 함께 정리합니다.