mkdir은 지정한 경로에 디렉터리를 만들고, rmdir은 비어 있는 디렉터리만 골라 제거하는 명령어다. 두 명령은 대칭적으로 보이지만 실제로는 비대칭적으로 설계돼 있다 — mkdir -p는 중간 경로까지 알아서 만들어 주는 반면, rmdir은 안에 무언가 하나라도 남아 있으면 무조건 실패한다.
이 장을 읽기 전에
선행 챕터: 이 장은 05장: touch에서 빈 파일을 만드는 법을 다룬 뒤 이어진다. 파일을 만드는 법을 알았으니, 이제 그 파일들을 담을 디렉터리를 만들고 지우는 법으로 넘어가는 자연스러운 흐름이다. mkdir·rmdir 자체는 01장: cd, pwd에서 다룬 경로 이동 개념 정도만 있으면 충분하다.
이 장의 깊이: 입문 난이도다. 디렉터리를 만들고 지우는 기본 옵션과 실무에서 자주 쓰는 조합을 다룬다. 다루지 않는 것: 비어 있지 않은 디렉터리를 통째로 삭제하는 재귀 삭제(rm -r)는 이 장의 범위가 아니다 — 그 이유와 방법은 07장: cp, mv, rm에서 다룬다. 권한 표기(755, 700 같은 8진수 모드)의 상세한 의미와 chmod로 기존 파일의 권한을 바꾸는 법은 36장: chmod, chown에서 다룬다.
당신의 수준에 맞는 경로
| 수준 | 읽을 부분 | 핵심 목표 |
|---|---|---|
| 디렉터리를 빨리 만들고 지워야 하는 사람 | “사용법·옵션”~“예시” | mkdir -p로 중첩 경로를 한 번에 만들고 rmdir로 빈 디렉터리를 정리한다 |
| 스크립트에 넣을 안전한 디렉터리 생성 로직이 필요한 사람 | “예시"부터 “흔한 오개념"까지 전체 | mkdir -p의 멱등성과 rmdir의 안전장치를 이해하고, umask가 만들어지는 디렉터리의 기본 권한에 어떻게 관여하는지 설명할 수 있다 |
개요 + 정신 모델
mkdir과 rmdir은 짝을 이루는 명령어처럼 보이지만, 둘이 “허용하는 범위"는 서로 다르게 설계돼 있다. mkdir -p는 목적지 경로에 이르는 중간 디렉터리가 없으면 군말 없이 다 만들어 준다 — mkdir -p a/b/c를 실행했을 때 a도 a/b도 없다면 셋 다 순서대로 생성한다. 반대로 rmdir은 “정말 비어 있는 디렉터리만” 지우도록 만들어졌고, 그 조건이 깨지면(파일이든 하위 디렉터리든 하나라도 남아 있으면) 아예 아무것도 지우지 않고 실패한다. 즉 생성은 관대하게, 삭제는 보수적으로라는 비대칭적 원칙이 두 명령어를 관통한다. 이 비대칭은 우연이 아니다 — 디렉터리를 만드는 실수는 되돌리기 쉽지만(다시 지우면 그만), 안에 내용물이 든 디렉터리를 실수로 지우는 것은 되돌릴 수 없는 데이터 손실이기 때문이다. rmdir은 그 위험을 원천적으로 차단하도록 설계됐고, 진짜 재귀 삭제가 필요한 순간에는 rm -r이라는 별도의, 더 명시적으로 위험한 명령을 쓰도록 셸 생태계 전체가 유도한다.
사용법·옵션
| |
두 명령 모두 인자로 디렉터리 경로를 하나 이상 받으며, 여러 개를 한 번에 지정하면 순서대로 처리한다.
mkdir 옵션
| 옵션 | 설명 |
|---|---|
-p, --parents | 상위 경로가 없으면 함께 생성한다. 대상 디렉터리가 이미 존재해도 에러 없이 조용히 성공한다 |
-m MODE, --mode=MODE | 생성할 디렉터리의 권한을 MODE(8진수)로 지정한다. 지정하지 않으면 777에서 현재 umask를 뺀 값이 적용된다 |
-v, --verbose | 디렉터리를 만들 때마다 메시지를 출력한다 |
rmdir 옵션
| 옵션 | 설명 |
|---|---|
-p, --parents | 지정한 경로와 그 상위 경로를 순서대로 제거한다. 상위 디렉터리 중 하나라도 비어 있지 않으면 그 지점에서 멈춘다 |
--ignore-fail-on-non-empty | 디렉터리가 비어 있지 않아 실패해도 에러를 무시하고 다음 인자로 넘어간다 |
-v, --verbose | 디렉터리를 지울 때마다 메시지를 출력한다 |
예시
중첩 디렉터리 한 번에 생성
| |
권한을 지정해 생성
| |
여러 디렉터리 한 번에 생성
| |
빈 디렉터리 삭제
| |
여러 디렉터리를 한 번에 삭제
| |
스크립트에서 멱등하게 디렉터리 준비
| |
주의사항·함정
rmdir은 비어 있지 않으면 반드시 실패한다 — 이것은 버그가 아니라 안전장치다. rmdir은 대상 디렉터리 안에 파일이든 하위 디렉터리든(숨김 파일 포함) 하나라도 남아 있으면 rmdir: failed to remove 'dir': Directory not empty라는 메시지와 함께 아무것도 지우지 않고 그대로 실패한다. 이 “전부 아니면 전무” 동작 덕분에 rmdir을 스크립트에 넣어도 실수로 내용물이 들어 있는 디렉터리가 통째로 사라지는 사고는 일어나지 않는다. 이 점에서 rmdir은 07장에서 다룰 rm -r과 정반대다 — rm -r은 내용물이 있어도 (확인 없이) 재귀적으로 지워 버리므로, “정말 비어 있는지 확인하고 지우고 싶다"는 의도가 있다면 rm -r 대신 rmdir을 쓰는 것 자체가 하나의 안전장치가 된다.
mkdir -p는 이미 있는 디렉터리에도 에러 없이 조용히 성공한다 — 스크립트 멱등성의 관용구다. -p 없이 mkdir dir을 실행했는데 dir이 이미 존재하면 mkdir: cannot create directory 'dir': File exists로 실패한다. 반면 mkdir -p dir은 대상이 이미 디렉터리로 존재하면 아무 일도 하지 않고 종료 코드 0을 반환한다(단, 같은 이름의 파일이 이미 있으면 이때는 -p를 써도 실패한다). 이 성질 때문에 배포·설치 스크립트에서 “이 디렉터리가 없으면 만들고, 있으면 그대로 둔다"는 로직을 조건문 없이 mkdir -p target_dir 한 줄로 표현하는 것이 표준 관용구로 자리 잡았다. 스크립트를 몇 번을 다시 실행해도 같은 상태로 수렴한다는 의미에서 이를 멱등성(idempotency)이라 부른다.
umask가 mkdir로 만든 디렉터리의 기본 권한을 결정한다. -m으로 모드를 명시하지 않고 mkdir을 실행하면, 생성되는 디렉터리의 권한은 디렉터리 최대 권한인 777에서 현재 셸의 umask 값을 뺀 값이 된다. 예를 들어 umask가 022(대부분의 리눅스 배포판 기본값)라면 mkdir newdir로 만든 디렉터리는 755(소유자 rwx, 그룹·기타 r-x) 권한을 갖는다. umask는 셸 세션 전체에 적용되는 전역 설정이라, 같은 mkdir 명령이라도 실행하는 셸의 umask 값에 따라 결과 권한이 달라질 수 있다는 점을 스크립트 작성 시 염두에 둬야 한다 — 특정 권한을 반드시 보장해야 한다면 umask에 기대지 말고 -m으로 명시하는 편이 안전하다.
흔한 오개념
"rmdir -p는 rm -r처럼 디렉터리 안의 내용물까지 재귀적으로 지워 준다”는 흔한 오해다. rmdir -p a/b/c의 -p는 “재귀 삭제"가 아니라 “지정한 경로와 그 상위 경로를 순서대로 지운다"는 뜻이다. 즉 a/b/c, a/b, a 세 디렉터리 각각이 비어 있어야 순서대로 지워지며, 그중 하나라도(예: a 아래에 a/b와 무관한 다른 파일이 있는 경우) 비어 있지 않으면 그 지점에서 멈추고 나머지는 그대로 남는다. 내용물이 있는 디렉터리를 하위까지 통째로 지우려면 애초에 rmdir이 아니라 rm -r을 써야 한다.
다음 장에서는
디렉터리는 만들고 지울 수 있게 됐으니, 이제 그 안의 내용물을 옮기고 지우는 법으로 넘어간다. 07장: cp, mv, rm에서는 파일과 디렉터리를 복사·이동하고, rmdir이 거부하는 “비어 있지 않은 디렉터리 삭제"를 rm -r로 어떻게 다루는지 다룬다.
평가 기준
mkdir -p가 중간 경로를 재귀적으로 생성하는 것과,rmdir이 반드시 빈 디렉터리만 지우는 것 사이의 비대칭을 설명할 수 있다.-m옵션으로 디렉터리 생성 시 권한을 직접 지정하고, 지정하지 않았을 때umask가 결과 권한에 어떻게 관여하는지 설명할 수 있다.mkdir -p가 이미 존재하는 디렉터리에 대해 에러 없이 성공하는 멱등성을 스크립트에서 활용할 수 있다.rmdir -p가 재귀 삭제가 아니라 상위 경로까지의 순차 삭제라는 점을 구분할 수 있다.
![Featured image of post [Bash Shell] 06. mkdir, rmdir - 디렉터리 생성과 삭제](/post/bashshell/mkdir-rmdir-commands-create-delete-directories/wordcloud_hu_3ba086147d61af39.webp)
![[Bash Shell] 04. less, more - 페이저로 파일 보기](/post/bashshell/less-more-commands-view-large-files-linux/wordcloud_hu_7ec28326489f97a8.webp)
![[Bash Shell] 05. touch - 파일 생성과 타임스탬프 갱신](/post/bashshell/touch-command-create-file-update-timestamp/wordcloud_hu_7ec28326489f97a8.webp)
![[Bash Shell] 06. mkdir, rmdir - 디렉터리 생성과 삭제](/post/bashshell/mkdir-rmdir-commands-create-delete-directories/wordcloud_hu_7ec28326489f97a8.webp)
![[Bash Shell] 07. cp, mv, rm - 파일 복사·이동·삭제](/post/bashshell/cp-mv-rm-commands-copy-move-delete-files/wordcloud_hu_7ec28326489f97a8.webp)
![[Bash Shell] 08. ln - 하드링크와 심볼릭 링크](/post/bashshell/ln-command-hard-symbolic-links-linux/wordcloud_hu_76b51dfeca0d4f59.webp)
![[Bash Shell] 03. cat, head, tail - 파일 내용 출력과 일부 보기](/post/bashshell/cat-head-tail-commands-view-file-contents/wordcloud_hu_7ec28326489f97a8.webp)
![[Bash Shell] 21. xargs - 인자 변환과 배치 실행](/post/bashshell/xargs-command-build-execute-command-lines/wordcloud_hu_7ec28326489f97a8.webp)
![[Bash Shell] 40. du, df - 디스크 사용량 확인](/post/bashshell/du-df-commands-disk-usage-linux/wordcloud_hu_13758518c299ef5e.webp)