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 강좌 / 프로세스 확인·일시정지·종료하기

Linux 강좌 / 프로세스 확인·일시정지·종료하기

ps, top, pgrep으로 프로세스의 상태와 자원 사용량을 확인합니다. 실습 프로세스에 STOP, CONT, TERM을 보내고 셸 작업과 서비스의 차이를 익힙니다.

Linux / 명령어 / cut - 행에서 문자와 필드 추출

Linux / 명령어 / cut - 행에서 문자와 필드 추출

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

Linux / 명령어 / traceroute - 목적지까지 라우터 경로 추적

Linux / 명령어 / traceroute - 목적지까지 라우터 경로 추적

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

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

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

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

Linux / 명령어 / dd - 블록 단위 데이터 복사와 변환

Linux / 명령어 / dd - 블록 단위 데이터 복사와 변환

Linux dd 명령어로 파일과 블록 장치 데이터를 복사하고 변환하는 방법을 설명합니다. if와 of, 블록 크기, 진행률, 디스크 이미지 생성·복원 및 대상 장치 오지정 위험을 정리합니다.

Linux / 명령어 / renice - 실행 중인 프로세스 nice 값 변경

Linux / 명령어 / renice - 실행 중인 프로세스 nice 값 변경

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

Linux / 명령어 / printf - 지정한 형식으로 값 출력

Linux / 명령어 / printf - 지정한 형식으로 값 출력

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

Linux / 명령어 / type - 명령어 유형과 실행 대상 확인

Linux / 명령어 / type - 명령어 유형과 실행 대상 확인

Bash type 명령어로 별칭, 예약어, 함수, 내장 명령과 실행 파일을 구분하는 방법을 설명합니다. 모든 후보와 경로 확인, command -v·which와의 차이 및 스크립트 활용법을 다룹니다.

Linux / 명령어 / bunzip2 - bzip2 압축 파일 풀기

Linux / 명령어 / bunzip2 - bzip2 압축 파일 풀기

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

Linux / 리눅스 Bash 명령어 연결 연산자: ;, &&, ||, &, | 사용법

Linux / 리눅스 Bash 명령어 연결 연산자: ;, &&, ||, &, | 사용법

리눅스 Bash의 ;, &&, ||, &, |, |&, ! 차이를 종료 상태와 실제 예제로 설명합니다. 조건부 실행, 백그라운드 작업, 파이프라인과 pipefail 사용법까지 정리합니다.