SSD Nodes Learn Hosting plans →
가이드 Matt Connor작성자 Matt Connor · 업데이트됨 2026-08-26

df와 du 용량 차이 원인과 해결 방법

df는 디스크 전체를, du는 파일 단위로 용량을 계산합니다. 삭제된 파일을 프로세스가 점유 중일 때 발생하는 공간 부족 문제를 lsof 명령어로 확인하고 재부팅 없이 해결하는 방법을 상세히 안내합니다.

Verified Every command ran end-to-end on a fresh Ubuntu 24.04 server, August 15, 2026.

df 명령은 디스크가 꽉 찼다고 하는데 du 명령은 그렇지 않은 이유

df은 디스크가 가득 찼다고 보고하지만, du은 공간을 찾지 못하는 경우가 있습니다. 이는 프로세스가 삭제된 파일을 여전히 붙잡고 있기 때문입니다. 파일을 삭제하면 디렉터리에서 파일 이름만 제거됩니다. 해당 inode를 가리키는 마지막 열린 파일 디스크립터가 닫혀야만 데이터 블록이 비로소 해제됩니다. du는 파일 이름을 따라 탐색하므로 삭제된 파일은 계산하지 않습니다. 반면 df은 파일 시스템에 할당된 블록 수를 직접 조회하므로, 이름이 사라진 파일도 여전히 용량에 포함합니다.

이 가이드에서는 기본 Ubuntu VPS 환경에서 이미 설치된 도구를 사용하여 해당 현상을 재현하고, /proc을 통해 파일을 붙잡고 있는 프로세스를 찾아 재부팅 없이 공간을 확보하는 방법을 다룹니다. 동일한 증상을 유발하는 다른 원인들인 inode 테이블의 여유 공간 부족, 마운트 지점 아래에 숨겨진 파일, root 사용자를 위해 예약된 블록에 대해서도 설명합니다.

각 명령어를 직접 실행하고 출력 결과를 확인하십시오. 값은 사용자의 디스크 환경에 따라 다르므로, 가이드에 적힌 수치와 비교하기보다 자신의 시스템에서 작업 전후의 변화를 직접 비교하시기 바랍니다.

df와 du가 집계하는 대상

df (disk free)는 마운트된 각 파일 시스템에 자체적인 집계 데이터를 요청합니다. 여기에는 존재하는 블록 수, 할당된 블록 수, 여유 블록 수가 포함됩니다. 이 명령어는 디렉터리를 열지 않습니다. 따라서 어떤 디렉터리 항목도 가리키지 않는 파일에 속한 블록을 포함하여, 할당된 모든 블록을 결과에 반영합니다.

du (disk usage)는 정반대로 동작합니다. 지정한 경로에서 시작하여 디렉터리를 읽고, 발견한 모든 항목의 상태(stat)를 확인한 뒤 블록 수를 합산합니다. 이름이 없는 파일은 이 명령어의 집계 대상에서 제외됩니다. 읽기 권한이 없는 디렉터리 역시 집계되지 않으며, 일반 사용자가 root보다 더 적은 합계를 얻는 이유가 바로 이것입니다. 비교를 통해 결론을 내리기 전에 반드시 dusudo 권한으로 실행하십시오.

두 명령어를 비교할 때 항상 고려해야 할 옵션이 두 가지 있습니다.

  • -xdu이 하나의 파일 시스템 내에서만 동작하도록 제한합니다. 이 옵션이 없으면 du // 하위에 마운트된 모든 파일 시스템을 탐색하며, 결과적으로 df /이 측정하지 않는 영역까지 포함한 합계를 출력하게 됩니다.
  • -s은 디렉터리별로 한 줄씩 출력하는 대신, 인자당 하나의 요약 줄만 출력합니다.

이 옵션들을 조합하면 관심 있는 파일 시스템에서 두 명령어를 나란히 실행하여 비교할 수 있습니다.

df -h /
sudo du -xhs / 2>/dev/null

df는 즉시 결과를 반환합니다. 반면 du은 모든 파일의 상태를 확인하며 탐색해야 하므로 대규모 파일 시스템에서는 수 분이 소요될 수 있습니다. 두 결과값의 차이가 크고, du-x 옵션과 함께 root 권한으로 실행했다면, 누락된 공간은 이름이 없는 무언가에 할당된 상태입니다.

의도적으로 불일치 상황 재현하기

테스트용 VPS에서 수행하십시오. 아래의 모든 작업은 bash와 coreutils를 사용하므로 별도의 소프트웨어를 설치할 필요가 없습니다.

/var/tmp이 위치한 파일 시스템의 시작 상태를 기록합니다.

cd /var/tmp
df -h .
df --output=used -B1 .

두 번째 명령어는 반올림 없이 사용된 바이트 수를 출력하므로 마지막 확인 단계에서 정확한 값을 얻을 수 있습니다.

이제 파일을 생성합니다. 파일 크기는 시스템이 보고하는 여유 공간을 기준으로 하므로, 어떤 디스크 환경에서도 실습이 가능합니다.

free=$(df --output=avail -B1 . | tail -n 1)
fallocate -l $((free / 10)) ghost.bin
ls -l ghost.bin
df -h .

$(...)은 명령 치환(command substitution)입니다. 셸이 내부 명령을 실행하고 그 출력값이 free의 값이 됩니다. 이 문법이 생소하다면 bash의 명령 치환에서 자세히 다루고 있습니다. fallocate는 데이터를 실제로 쓰지 않고 블록만 예약하므로 즉시 완료됩니다. 이를 지원하지 않는 파일 시스템에서는 명령이 실패하며, 이때는 head -c $((free / 10)) /dev/zero > ghost.bin을 사용하여 바이트를 직접 기록함으로써 동일한 작업을 수행할 수 있습니다.

df -h . 결과를 처음에 기록한 값과 비교하십시오. 사용된 공간(used) 열은 증가했고, 사용 가능한 공간(available) 열은 줄어들었을 것입니다.

이제 다른 프로세스에서 파일을 열어둔 상태로 파일을 삭제합니다.

sleep infinity < ghost.bin &
holder=$!
rm ghost.bin
ls -l ghost.bin
df -h .
sudo du -xhs . 2>/dev/null

리다이렉션이 이 작업의 핵심입니다. sleep infinity < ghost.bin &는 해당 파일을 표준 입력으로 사용하는 백그라운드 프로세스를 시작합니다. 셸이 파일을 열어 파일 디스크립터를 sleep에 전달하고, 이 프로세스가 파일을 계속 열어두게 됩니다. $!는 해당 백그라운드 작업의 프로세스 ID를 보관합니다. 그 후 rm를 실행하여 파일 디스크립터가 열려 있는 상태에서 파일 이름을 삭제합니다.

출력 결과를 확인하십시오. ls은 파일 이름을 찾을 수 없으므로 파일을 찾지 못합니다. du은 파일 이름을 기준으로 탐색하므로 시작 시점과 거의 동일한 상태로 돌아옵니다. df은 블록이 여전히 할당되어 있으므로 변화가 없습니다. 이제 파일 시스템과 디렉터리 트리 간에 불일치가 발생했으며, 그 차이만큼의 공간이 방금 삭제한 파일이 차지하고 있는 영역입니다.

삭제된 파일을 점유 중인 프로세스 찾기

모든 열린 파일 디스크립터는 /proc/<pid>/fd/ 아래에 해당 파일을 가리키는 심볼릭 링크로 나타납니다. 파일이 언링크(unlink)되면 커널은 해당 링크의 대상을 삭제된 것으로 표시합니다. 따라서 점유자를 찾는다는 것은 삭제 표시가 된 대상을 가리키는 링크를 찾는다는 의미입니다.

sudo find /proc/[0-9]*/fd -lname '*(deleted)' -printf '%p -> %l\n' 2>/dev/null

-lname은 심볼릭 링크의 이름이 아닌 대상을 매칭하며, %p은 디스크립터 경로를 출력하고, %l는 해당 경로가 가리키는 대상을 출력합니다. 출력된 경로의 두 번째 요소가 프로세스 ID입니다. sudo 권한으로 실행하십시오. 그렇지 않으면 본인 소유의 프로세스에 대한 /proc/<pid>/fd만 읽을 수 있습니다. 표준 에러 리다이렉션은 find가 탐색하는 도중 종료되는 프로세스에서 발생하는 불필요한 메시지를 제거합니다.

운영 중인 서버는 항상 여러 개의 삭제된 파일을 점유하고 있으며, 대부분은 크기가 작고 무해합니다. 크기순으로 정렬하여 중요한 파일만 상단에 나타나도록 합니다.

sudo bash -c 'for fd in /proc/[0-9]*/fd/*; do
  target=$(readlink "$fd" 2>/dev/null) || continue
  case "$target" in
    *"(deleted)") echo "$(stat -Lc %s "$fd" 2>/dev/null) $fd $target" ;;
  esac
done' | sort -rn | head

stat -L은 링크를 따라 inode 자체를 참조하므로, %s은 더 이상 이름이 없는 파일의 크기를 보고합니다. 이 숫자를 기준으로 정렬하면 가장 큰 파일이 맨 위로 올라옵니다.

그다음, 상위 디스크립터를 점유 중인 프로세스를 식별합니다. 목록 상단의 경로에는 필요한 두 가지 숫자가 모두 포함되어 있습니다. 먼저 해당 숫자를 변수에 할당하십시오. 이때 PID와 N은 직접 출력한 결과값으로 대체합니다.

pid=PID
n=N
ps -o pid,user,etime,args -p "$pid"
sudo stat -L "/proc/$pid/fd/$n"

ps은 프로그램 이름을 명시하고 실행 시간을 보여줍니다. stat -L는 삭제된 inode의 크기와 할당된 블록 수를 출력합니다. 이 정보들을 종합하면 어떤 서비스가 해당 파일을 유지하고 있는지 확인할 수 있습니다.

시스템에 이미 lsof이 설치되어 있다면, sudo lsof +L1을 사용하여 링크 카운트가 0이 된 열린 파일들을 크기별로 표 형식으로 나열할 수 있습니다. 최소 설치된 Ubuntu 이미지에는 이 도구가 포함되어 있지 않으며, 디스크 공간이 부족한 상태에서 패키지를 설치하는 것 자체가 실패할 수 있으므로 /proc를 이용한 탐색 방식이 언제나 작동하는 방법입니다.

재부팅 없이 공간 확보하기

재부팅으로 문제를 해결할 수는 있지만, 이는 올바른 첫 번째 대응이 아닙니다. 서비스가 중단되고 증거가 사라지기 때문입니다. 더 안전한 네 가지 방법을 시도 순서대로 설명합니다.

데이터가 필요하다면 먼저 복사하십시오. 기술자 경로를 읽으면 실시간 inode를 읽을 수 있습니다.

sudo cp /proc/<pid>/fd/<n> /root/recovered.log

삭제된 파일을 복구하기 쉬운 유일한 경우입니다. 이것이 바로 rm -rf로 삭제된 파일 복구하기에서 프로세스가 파일을 열고 있는지 먼저 확인하는 이유입니다. 마지막 기술자가 닫히면 해당 경로는 사라집니다.

두 번째로, 기술자를 통해 파일을 비우십시오. /proc 경로는 동일한 inode로 연결되므로, 파일을 자르면 프로세스가 실행 중인 상태에서도 블록이 해제됩니다.

sudo truncate -s 0 "/proc/$pid/fd/$n"
df -h /

작성자가 파일을 추가 모드(append mode)로 열었을 때 이 방법이 깔끔하게 작동합니다. 모든 쓰기 작업이 파일의 현재 끝부분에서 이루어지기 때문입니다. 그렇지 않은 경우, 프로세스는 이전 쓰기 오프셋을 유지하므로 다음 쓰기 작업은 파일의 훨씬 뒤쪽에서 수행되어 앞부분에 빈 공간(hole)이 생깁니다. 빈 공간은 할당되지 않으므로 블록은 계속 비어 있고 df는 방금 반환한 공간을 유지합니다. 다시 커지는 것은 파일 크기뿐입니다. 프로세스가 쓰기를 수행한 후 sudo stat -L "/proc/$pid/fd/$n"를 다시 실행하면, 블록 수와 일치하지 않는 이전 크기가 표시됩니다. 크기를 0부터 다시 시작하려면 프로세스를 재시작하십시오.

세 번째로, 서비스에 로그를 다시 열도록 요청하십시오. 로그 파일이 삭제된 데몬이 이 문제의 가장 흔한 실제 사례입니다. 많은 데몬이 신호를 받으면 로그 파일을 다시 엽니다. nginx는 SIGUSR1을 사용하고 rsyslog는 SIGHUP을 사용합니다. 잘못된 신호를 보내면 데몬이 중단될 수 있으므로 추측하지 말고 해당 데몬의 문서를 확인하십시오.

sudo systemctl kill -s USR1 nginx

이 명령은 systemd가 유닛의 메인 프로세스로 기록한 대상에 신호를 보냅니다. 따라서 데몬의 실제 시작 방식과 다른 잘못된 Type=을 선언한 유닛은 삭제된 파일을 보유하지 않은 프로세스에 신호를 전달할 수 있으며, 이 경우 공간은 확보되지 않습니다.

네 번째로, 유닛을 재시작하십시오. sudo systemctl restart <unit>은 이전 프로세스가 보유했던 모든 기술자를 닫으므로 블록이 확실하게 반환됩니다. 위 예시에서 파일을 보유한 주체는 직접 시작한 sleep이므로, 이를 종료하는 것만으로 충분합니다.

kill $holder
df -h .
df --output=used -B1 .
sudo find /proc/[0-9]*/fd -lname '*(deleted)' -printf '%p -> %l\n' 2>/dev/null

사용된 바이트 수를 파일을 생성하기 전에 기록한 값과 비교하십시오. 다시 일치할 것이며, find은 더 이상 해당 기술자를 보고하지 않습니다. 문제를 발견했던 동일한 명령으로 확인하는 습관을 들이는 것이 좋습니다.

값이 변하는 것을 지켜보는 것이 df를 반복해서 수동으로 실행하는 것보다 쉽습니다. watch는 고정된 간격으로 명령을 반복하고 출력을 제자리에 다시 표시하므로, watch df -h /을 사용하면 공간이 돌아올 때 사용량 열이 변하는 것을 확인할 수 있습니다.

합계는 일치하지만 디스크가 여전히 가득 찬 경우

df와 루트 du -x의 결과가 서로 일치한다면, 삭제된 파일이 원인은 아닙니다. 남은 원인들은 성격이 다르며, 각각 별도의 확인 절차가 필요합니다.

블록은 남았으나 아이노드(inode)가 부족한 경우

아이노드는 파일 하나에 대한 메타데이터를 저장합니다. ext4 파일 시스템은 생성 시점에 고정된 개수의 아이노드를 할당하므로, 디스크 블록은 남아있어도 아이노드가 먼저 고갈될 수 있습니다. 이 경우 df -h 명령어로 확인했을 때 여유 공간이 있어도 새로운 파일을 생성할 수 없습니다.

df -h /
df -i /

첫 번째 명령어는 블록을, 두 번째 명령어는 아이노드를 계산합니다. 각 결과의 사용률(use) 열을 비교하십시오. 블록 사용량은 낮으나 아이노드 사용량이 한계치에 도달했다면, 매우 작은 파일이 다수 생성되어 발생하는 문제입니다.

df는 동일한 호출 내에서 -i--output 옵션을 동시에 사용할 수 없습니다. 따라서 원시 데이터를 읽거나 다른 명령어의 입력값으로 전달하려면, 아이노드 필드를 이름으로 지정하고 -i 옵션은 제외하십시오.

df --output=itotal,iused,iavail,ipcent /

해당 열들은 df -i이 출력하는 것과 동일한 계정 정보를 담고 있으며, 이를 통해 데이터를 추출할 수 있습니다.

바이트 단위가 아닌 항목 개수를 세어 파일을 찾으십시오.

sudo du --inodes -x -d 1 / 2>/dev/null | sort -rn | head

가장 많은 항목이 발견된 디렉터리를 대상으로 하위 단계에서 동일한 명령을 반복하여, 파일을 대량으로 생성하는 경로를 찾으십시오. 사용 중인 du--inodes 옵션을 지원하지 않는다면, sudo find /var -xdev -type f | wc -l을 사용하여 하위 트리의 개수를 느리게 계산할 수 있습니다.

해결 방법은 해당 파일들을 삭제하거나 이동하는 것입니다. ext4 파일 시스템은 mkfs 시점에 아이노드 개수가 고정되므로, 기존 파일 시스템에서 아이노드 수를 늘릴 수 없습니다. 이를 늘리려면 파일 시스템을 다시 생성하고 백업에서 데이터를 복구해야 합니다. XFS는 필요에 따라 아이노드를 동적으로 할당하므로 이와 같은 고정된 제한을 겪지 않습니다. 컨테이너를 운영하는 서버는 이미지 레이어에 작은 파일이 많이 포함되어 있어 두 가지 제한 모두 일반적인 경우보다 빨리 도달합니다. 해당 환경에서는 VPS에서 Docker 디스크 사용량 정리하기가 구체적인 해결책이며, 이는 파일 시스템 전체를 정리하는 것보다 훨씬 많은 공간을 확보해 줍니다.

마운트 지점 아래에 숨겨진 공간

디렉터리에 무언가를 마운트하기 전에는 해당 디렉터리에 파일이 존재할 수 있습니다. 그 디렉터리 위에 파일 시스템을 마운트하면, 아래에 있던 파일들은 그대로 남습니다. 여전히 할당된 상태이며 df 명령어로 계산되지만, 이름으로는 더 이상 접근할 수 없습니다. 마운트가 해당 경로를 덮어버리기 때문에 du 명령어로도 볼 수 없습니다.

별도의 디스크 공간이 필요 없는 tmpfs를 사용하여 이를 확인해 보겠습니다. 이 과정은 마운트 권한이 필요한 작업이므로 KVM VPS 환경에서 수행해야 합니다.

sudo mkdir -p /srv/covered
sudo cp /etc/services /srv/covered/
ls /srv/covered
sudo mount -t tmpfs tmpfs /srv/covered
ls /srv/covered
sudo umount /srv/covered
ls /srv/covered

중간의 ls 출력 결과는 빈 디렉터리를 보여줍니다. 복사본은 사라진 것이 아니라 루트 파일 시스템에 그대로 남아 있으며, 마운트를 해제하는 즉시 다시 나타납니다. 누군가 볼륨을 마운트하기 전까지 한 달 동안 해당 경로에 로그를 기록하던 서비스를 상상해 보십시오.

실행 중인 서버에서 실제 데이터를 찾으려면, 루트 파일 시스템을 다른 위치에 한 번 더 마운트하면 됩니다. 바인드 마운트(bind mount)를 사용하면 내부에 마운트된 파일 시스템을 제외한 원래의 파일 시스템만 볼 수 있습니다.

sudo mkdir -p /mnt/rootcheck
sudo mount --bind / /mnt/rootcheck
sudo du -xhs /mnt/rootcheck/* 2>/dev/null | sort -h
sudo umount /mnt/rootcheck

일반 경로에서는 보이지 않지만 해당 목록에 나타나는 모든 파일은 마운트 지점 아래에 숨겨진 것입니다. 작업이 끝나면 바인드 마운트를 해제하십시오. 그렇지 않으면 -x 옵션이 없는 du 명령어가 동일한 파일을 두 번 계산하게 됩니다.

root 사용자를 위해 예약된 블록

ext4는 디스크가 가득 차더라도 root 사용자가 로그인하여 시스템을 복구할 수 있도록 블록의 일부를 root 사용자용으로 예약해 둡니다. 일반 사용자로 실행되는 프로세스는 디스크가 꽉 차면 즉시 쓰기 오류를 겪게 되지만, df 명령을 실행하면 여전히 약간의 공간이 남아 있는 것으로 표시됩니다. 기본값을 가정하지 말고 자신의 파일 시스템에서 현재 설정을 직접 확인하십시오.

dev=$(df --output=source / | tail -n 1)
sudo tune2fs -l "$dev" | grep -i 'block count'

이 명령은 전체 블록 수와 예약된 블록 수를 동일한 단위로 출력하므로, 두 값의 비율을 직접 계산할 수 있습니다. df 명령은 일반 사용자가 사용할 수 있는 공간을 available 열에 표시합니다. 이것이 바로 사용된 공간과 사용 가능한 공간을 합친 값이 전체 크기보다 작게 나타나는 이유입니다. 그 차이만큼이 예약된 공간입니다.

예약된 블록 수를 변경하려면 sudo tune2fs -m <percent> "$dev" 명령을 사용하십시오. 변경 사항은 즉시 적용되며 리마운트가 필요하지 않습니다. 별도의 데이터 파일 시스템이라면 예약 공간을 줄이는 것이 합리적입니다. 하지만 root 파일 시스템의 경우 root 사용자가 여전히 쓰기 작업을 수행할 수 있도록 충분한 공간을 남겨두어야 합니다. 파일 시스템에 여유 공간이 전혀 없으면 복구가 훨씬 어려워지기 때문입니다. 또한 이는 시스템 잠김을 방지하는 최후의 보루이기도 합니다. 공간이 전혀 없는 파일 시스템의 authorized_keys 파일에 키를 추가하려고 하면, 키가 잘리거나 아예 기록되지 않을 수 있습니다. 이 경우 다음 로그인 시 키 자체의 문제와는 무관하게 Permission denied (publickey) 오류가 발생합니다. tune2fs 명령은 ext2, ext3, ext4 파일 시스템에서 작동합니다. XFS에는 이와 대응하는 설정이 없습니다.

du가 단독으로 사용될 때 오해를 불러일으키는 경우

du의 네 가지 습관은 잘못된 것처럼 보이는 합계를 생성합니다.

  • 하드 링크: du는 여러 이름이 하나의 inode를 가리키더라도 해당 inode를 한 번만 계산합니다. 따라서 하드 링크가 가득 찬 트리는 실제 파일 크기의 합보다 작게 보고됩니다.
  • 스파스 파일: du는 실제로 할당된 블록을 보고하는 반면, ls -l은 명목상 크기를 보고합니다. 다른 수치를 확인하려면 --apparent-size을 추가하십시오.
  • 권한: 일반 사용자로 실행하면 du은 읽을 수 없는 파일을 건너뛰고 실제보다 적게 보고합니다. 이때 출력되는 오류 메시지는 사용자가 흔히 /dev/null로 리다이렉트하여 무시해 버리는 내용입니다.
  • 파일 시스템 경계: -x 옵션이 없으면 du // 아래에 마운트된 모든 파일 시스템을 계산합니다. 따라서 그 합계가 df /이 보고하는 수치를 초과할 수 있습니다.

df 또한 알아두어야 할 특징이 하나 있습니다. 이 명령어는 각 파일 시스템을 별도로 보고하므로, 쓰기 실패가 발생하는 정확한 경로를 대상으로 실행해야 합니다. 별도의 /boot는 커널 패키지가 누적됨에 따라 자체적인 일정에 맞춰 가득 차게 되며, Ubuntu에서 오래된 커널 제거하기/의 공간을 확보하는 작업과는 별개의 과정입니다.

실제 장애 발생 시 대응 절차

  1. 쓰기 실패가 발생한 대상 파일시스템에서 df -h <path>df -i <path>을 실행하십시오. 반사적으로 /에서 실행해서는 안 됩니다.
  2. sudo du -xh -d 1 <mountpoint> 2>/dev/null | sort -h을 실행한 뒤, 가장 용량이 큰 디렉터리로 이동하십시오.
  3. df가 보고하는 사용량과 du의 결과가 일치하지 않는다면, /proc에서 삭제되었으나 여전히 열려 있는 파일을 찾으십시오.
  4. 두 도구의 결과가 일치한다면, 해당 파일시스템을 다른 경로에 bind mount하여 마운트 지점 아래에 숨겨진 파일이 있는지 확인하십시오.
  5. inode 사용량이 한계치에 도달했다면, 바이트 단위가 아닌 파일 개수를 세어야 합니다.

위의 각 단계는 출력 결과를 직접 읽을 수 있는 명령어로 구성되어 있습니다. 이것이 추측에 의존하지 않고 문제를 해결하는 방법입니다.

FAQ

df 명령은 디스크가 꽉 찼다고 나오는데 du 명령은 훨씬 적게 사용하는 이유는 무엇입니까?

일반적인 원인은 프로세스가 파일을 열어둔 상태에서 해당 파일이 삭제되었기 때문입니다. 파일을 삭제하면 디렉터리 항목에서 제거되므로 du는 파일 이름을 찾을 수 없어 계산에서 제외합니다. 하지만 마지막 파일 기술자(descriptor)가 닫힐 때까지 inode와 블록은 할당된 상태로 유지되며, df는 할당된 블록을 모두 계산합니다. /proc/<pid>/fd에서 대상이 삭제된 것으로 표시된 심볼릭 링크를 검색하면 해당 파일과 이를 붙잡고 있는 프로세스를 찾을 수 있습니다. 비교 결과를 신뢰하기 전에 du을 root 권한으로 -x 옵션과 함께 실행했는지 확인하십시오. 일반 사용자로 실행하면 읽기 권한이 없는 디렉터리를 조용히 건너뛰기 때문입니다.

lsof 없이 열려 있는 삭제된 파일을 어떻게 찾습니까?

커널이 관리하는 열린 기술자 기록을 사용하십시오. sudo find /proc/[0-9]*/fd -lname '*(deleted)' -printf '%p -> %l\n' 2>/dev/null는 이름이 없는 파일을 가리키는 모든 기술자를 나열하며, 출력되는 경로 안에 프로세스 ID가 포함되어 있습니다. 해당 기술자 경로 중 하나에 sudo stat -Lc %s을 실행하면 파일 크기를 확인할 수 있으므로, 이를 정렬하여 중요한 파일을 골라낼 수 있습니다. 이 방법은 별도의 패키지 설치가 필요 없으며, 디스크 공간이 부족하여 패키지 설치가 실패할 수 있는 상황에서 유용합니다.

프로세스를 종료하지 않고 공간을 확보할 수 있습니까?

가능할 때가 있습니다. sudo truncate -s 0 /proc/<pid>/fd/<n>을 사용하여 기술자를 통해 동일한 inode에 접근하면 프로세스가 계속 실행 중인 상태에서도 블록을 해제할 수 있습니다. 프로세스가 파일을 append 모드로 열었다면 쓰기 작업이 항상 파일 끝에서 이루어지므로 가장 깔끔하게 처리됩니다. 그렇지 않은 경우 쓰기 오프셋이 이전 위치에 머물러 있어, 다음 쓰기 작업 시 파일 앞부분에 빈 공간(hole)이 생기며 파일이 다시 생성됩니다. 이로 인해 보고되는 크기는 다시 늘어나지만 빈 공간 아래의 블록은 계속 비어 있게 됩니다. 가장 확실한 해결책은 해당 유닛을 재시작하거나, 문서에 명시된 신호를 보내 로그 파일을 다시 열게 하여 스파스 파일(sparse file)이 남지 않도록 하는 것입니다.

df 명령은 여유 공간이 있다고 나오는데 쓰기 작업이 실패하는 이유는 무엇입니까?

df -i 명령으로 동일한 경로의 inode 상태를 확인하십시오. 블록은 남아 있어도 inode가 모두 소진되면 새 파일을 생성할 수 없습니다. root가 아닌 사용자가 ext4 파일시스템에 쓰기를 시도할 때 예약된 블록만 남아 있는 경우일 수 있으며, 이는 장치에 대해 sudo tune2fs -l을 실행하면 확인할 수 있습니다. 또한 쓰기 작업이 실제로 수행되는 파일시스템을 보고 있는지 확인하십시오. 별도의 /boot/var/과 독립적으로 용량이 차오르기 때문입니다.

du 명령이 df 명령보다 더 큰 합계를 보고하는 이유는 무엇입니까?

-x 옵션 없이 du을 실행하면 지정한 경로 아래에 마운트된 모든 파일시스템을 넘나들며 계산하므로 여러 파일시스템의 합계가 출력되지만, df는 하나의 파일시스템만 설명합니다. 바인드 마운트(bind mount)가 되어 있다면 동일한 파일이 각 경로마다 중복 계산되어 문제가 더 커집니다. -x 옵션을 추가하여 du이 단일 파일시스템 내에 머물도록 하고, df에도 동일한 경로를 지정하여 두 명령이 같은 대상을 설명하도록 하십시오.