Devin.KR
로그인

리눅스 du 명령어 사용법 - 디스크 용량 잡아먹는 디렉터리 찾기

개발자 조회 2

이 명령어를 언제 쓰는가

df로 /가 92% 찼다는 걸 알았다. 그다음 할 일은 어디가 먹고 있는지 찾는 것이고, 그게 du다.

실무에서 du는 거의 언제나 위에서 아래로 좁혀 가는 방식으로 쓴다. 루트에서 한 단계씩 내려가며 가장 큰 디렉터리를 고르고, 그 안에서 다시 한 단계를 본다. 처음부터 du -sh /*로 전부 훑으면 몇 분씩 걸리고 정작 원인은 안 보인다.

기본 형식

du [옵션] [경로...]

경로를 생략하면 현재 디렉터리다. 옵션 없이 치면 하위 모든 디렉터리를 한 줄씩 다 뱉으므로 실용적이지 않고, 실제로는 -h, -d, -s를 조합해서 쓴다.

자주 쓰는 옵션

옵션의미예시
-h사람이 읽는 단위로 표시du -h
-s하위를 나열하지 않고 합계만du -sh /var/log
-d NN 단계까지만 내려간다(--max-depth=N)du -h -d1 /var
-x다른 파일시스템으로 넘어가지 않는다du -h -d1 -x /
-a디렉터리뿐 아니라 개별 파일도 표시du -ah /tmp | sort -h | tail
-c맨 끝에 총합 행 추가du -csh /var/log/*.gz
--apparent-size할당 블록이 아닌 논리적 파일 크기du -sh --apparent-size /data
--exclude=패턴패턴에 맞는 항목 제외du -sh --exclude='*.log' /app
--time마지막 수정 시각도 함께du -h -d1 --time /backup

실전 예제

1) 루트부터 한 단계씩 좁혀 들어간다. 디스크 풀 장애의 표준 절차다. -x가 핵심이라 /proc, /sys, 마운트된 NFS로 새지 않는다. sort -h는 "1.2G"와 "980M"을 제대로 비교한다.

sudo du -h -d1 -x / 2>/dev/null | sort -h | tail -10
132M	/etc
420M	/root
1.1G	/usr
2.3G	/home
8.7G	/var
24G	/opt
38G	/

2) 지목된 디렉터리 안을 다시 본다. 위 결과에서 /var가 크니 한 단계 더 들어간다. 이 과정을 원인을 찾을 때까지 반복한다.

sudo du -h -d1 -x /var 2>/dev/null | sort -h | tail

3) 로그 디렉터리에서 큰 것부터 나열한다. 로테이션이 안 도는 파일을 잡아낼 때 쓴다.

sudo du -sh /var/log/* | sort -h | tail -10

4) 특정 크기 이상의 파일만 직접 찾는다. 디렉터리 합계가 아니라 개별 대용량 파일이 범인일 때는 du보다 find가 정확하고 빠르다.

sudo find /var -xdev -type f -size +500M -exec ls -lh {} + 2>/dev/null

5) 백업 대상 크기를 미리 잰다. 로그를 뺀 애플리케이션 디렉터리가 얼마나 되는지 확인해 백업 용량을 산정한다.

du -csh --exclude='*.log' --exclude='node_modules' /opt/myapp/*

함정과 주의점

-x 없이 루트를 훑지 마라. du는 마운트 경계를 신경 쓰지 않는다. NFS나 원격 스토리지가 마운트돼 있으면 네트워크 너머까지 전부 읽어서 명령이 몇십 분씩 걸리고, 로컬 디스크를 찾는 목적에도 맞지 않는다. /proc과 /sys의 가상 파일도 노이즈가 된다. 루트에서 시작할 때는 -x를 조건반사처럼 붙인다.

일반 사용자로 돌리면 값이 실제보다 작게 나온다. 읽기 권한이 없는 디렉터리는 에러만 stderr로 내고 합계에서 조용히 빠진다. 2>/dev/null로 에러를 감추면 이 사실조차 안 보인다. 디스크 조사는 sudo로 하는 것이 원칙이다.

du 합계와 df 사용량이 다르다. 셋 중 하나다. 첫째, 삭제됐지만 프로세스가 열고 있는 파일(df에만 잡힌다). 둘째, 마운트 지점 아래에 가려진 파일 — 디렉터리에 파일을 넣어 둔 뒤 그 위에 볼륨을 마운트하면 df에는 잡히고 du에는 안 보인다. 셋째, 파일시스템 메타데이터와 예약 블록. df 쪽이 크고 du가 작으면 대개 첫 번째 경우다.

du는 실제로 할당된 블록을 센다. 1바이트 파일도 보통 4KB를 차지한다. 작은 파일이 수십만 개면 du 값이 파일 크기 합보다 훨씬 크게 나온다. 반대로 sparse 파일(가상 머신 디스크 이미지 등)은 논리 크기보다 훨씬 작게 나온다. 논리 크기를 보려면 --apparent-size를 쓴다. 또 하드링크로 이어진 파일은 한 번만 계산되므로, rsync 하드링크 방식 백업 디렉터리를 개별로 재면 합이 안 맞는다.

macOS에서는 옵션이 다르다. BSD du에는 -d는 있지만 --max-depth, --exclude 같은 GNU 확장이 없다. 반면 sort -h는 macOS 기본 sort(BSD sort)에도 있으므로 그대로 쓸 수 있다. GNU 전용 옵션이 꼭 필요하면 brew install coreutilsgdu, gsort를 쓴다.

함께 보면 좋은 명령어

  • df — 항상 df로 먼저 어느 파일시스템인지 확인하고 du로 들어간다. 순서가 반대면 시간을 낭비한다.
  • find — 디렉터리 합계가 아니라 개별 대용량 파일이나 오래된 파일을 찾을 때는 find가 낫다.
  • ncdu — du 결과를 대화형으로 탐색하고 그 자리에서 지울 수 있다. 반복 조사가 필요하면 시간을 크게 줄여 준다.