【Linux】du・dfでディスク使用量を調べる方法|削除したのに容量が減らない罠

du(disk usage)とdf(disk free)は、どちらも「ディスクの使用量」を調べるコマンドですが、見ている対象がまったく違いますdu指定したファイル・ディレクトリがどれだけ容量を使っているかを調べ、dfファイルシステム全体(マウントポイント単位)の空き容量を調べます。「どのフォルダが容量を食っているか」はdu、「サーバー全体の空きはあとどれくらいか」はdfと使い分けます。

この記事では、実機のLinux(WSLのDebian)で両方の基本を確認したあと、「ファイルをrmで削除したのにdfの空き容量が増えない」という、経験者でも戸惑う有名な罠を実際に再現します。原因は「削除はしたが、まだどこかのプロセスがそのファイルを開いたまま」という、Linuxのファイルシステムならではの仕組みにあります。

先に結論

  • duファイル・ディレクトリ単位の使用量、dfファイルシステム全体の空き容量です。
  • 見やすい単位で表示するには両方とも-h(human-readable)を付けます。
  • ディレクトリごとの集計はdu --max-depth=1-d 1)です。
  • du ... | sort -rhで、容量の大きい順に並べられます。
  • 削除済みでもプロセスが開いたままのファイルは、duには見えないのにdfの容量は減りません
  • この状態は、そのファイルを開いているプロセスを終了(または再起動)すると解消します。

大きいファイルを探すfindコマンド、結果を大きい順に並べるsort、プロセスを確認・終了するps・killもあわせて参考になります。

スポンサーリンク

duの基本:ファイル・ディレクトリの使用量

duは、指定したパス以下のディスク使用量を表示します。-s(合計のみ)-h(読みやすい単位)を組み合わせたdu -shが最もよく使う形です。

du の基本
# 指定ディレクトリの合計サイズ(-s: 合計だけ, -h: 読みやすい単位)
du -sh .
# 8.1M	.

# サブディレクトリごとの内訳も見たいときは -s を外す
du -h .
# 8.1M	./sub
# 8.1M	.

# 1階層下だけを集計(深すぎる内訳を避ける)
du -h --max-depth=1 .
# 8.1M	./sub
# 8.1M	.

実機でも、du -sh .カレントディレクトリ以下の合計サイズが一目で分かる形式(8.1Mなど)で表示されました。-sを外すとサブディレクトリごとの内訳まで表示され、階層が深いと大量に出力されるため、--max-depth=1(短縮形-d 1)で「1階層下まで」に絞るのが定番です。「このサーバー、どこが容量を食っているんだろう」と調べるときの出発点になります。

sortと組み合わせて大きい順に並べる

duの結果をsortに渡すと、容量の大きいディレクトリから順に並べられます。sort-hオプションは、10M1.1Mのような人間向けの単位表記も正しく数値として比較してくれます。

大きいディレクトリを見つける
# --max-depth=1 の結果を、容量の大きい順に並べ替える
du -h --max-depth=1 . | sort -rh
# 12M	.
# 11M	./big
# 1.1M	./small

# -r: 降順, -h: 単位(K/M/G)を認識して数値として比較

実機でも、du -h --max-depth=1 . | sort -rh11Mのディレクトリが1.1Mのディレクトリより上に正しく並びました。通常のsort -nは数値専用で、単位付きの文字列(11Mなど)は正しく並び替えられませんが、sort-h(human-numeric-sort)を使えばこの問題を回避できます。「サーバーの容量を圧迫しているディレクトリ・トップ5」を調べたいときの定番の組み合わせです。

dfの基本:ファイルシステム全体の空き容量

dfduとは違い、マウントされているファイルシステム全体の使用量・空き容量を表示します。「サーバー全体、あとどれくらい空いているか」を調べるコマンドです。

df の基本
# 見やすい単位(-h)で表示
df -h .
# Filesystem      Size  Used Avail Use% Mounted on
# /dev/sdd        251G  460M  238G   1% /

# -h を付けないと、既定は1Kブロック単位で読みにくい
df .
# Filesystem     1K-blocks   Used Available Use% Mounted on
# /dev/sdd       263112772 470780 249203836   1% /

実機でも、df -hを付けると251G460Mのような読みやすい単位で表示され、付けないと1Kブロック単位の生の数値263112772など)で表示されて非常に読みにくいことを確認しました。duと同様、dfほぼ常に-hを付けて使うと考えてよいでしょう。Use%列が100%に近づいたら要注意のサインです。

【最重要】削除したのに容量が減らない罠

dudfの違いが最も強烈に表れるのがこの現象です。ファイルをrmで削除しても、そのファイルをまだ開いているプロセスがあると、実際のディスク容量は解放されませんduでは見えなくなるのに、dfの空き容量は増えないという、一見矛盾した状態になります。

削除済みでも容量が解放されない再現
# 20MBのファイルを作成
dd if=/dev/zero of=bigfile.bin bs=1M count=20

# 別プロセス(この例ではファイルディスクリプタ)で開いたままにする
exec 9< bigfile.bin

# その状態で rm しても…
rm bigfile.bin
ls bigfile.bin
# ls: cannot access 'bigfile.bin': No such file or directory
#   ↑ ファイルは「無い」ことになっている

du -sh .
# 変化なし(duにはもう見えない = ディレクトリツリーには存在しない)

df -h .
#   ↑ 使用量は rm 前とほとんど変わらない!(容量は解放されていない)

# ファイルを開いていたプロセス(この例ではfd 9)を閉じると…
exec 9<&-
df -h .
#   ↑ ここでようやく使用量が減る(約20MB分、解放された)
rm後もdfの使用量が変わらない(実証)

実機で、20MBのファイルを作成し、ファイルディスクリプタで開いたままrmで削除したところ、lsでは「存在しない」扱いになり、duの集計からも消えました。しかしdfの使用量はrmの前後でまったく変わりませんでした488188KBのまま)。そしてそのファイルを開いていた側(プロセスやファイルディスクリプタ)を閉じた瞬間、dfの使用量が約20MB分(20480KB)減少し、削除したファイルのサイズとぴったり一致しました。Linuxでは、ファイルの実体は「開いているプロセスが0個になって初めて」本当に削除されますrmはディレクトリからの「名前」を消すだけで、実体(inode)はまだ誰かが参照していれば残るのです。ログファイルを大きくしたまま長時間動いているプロセス(Webサーバーなど)をrmしても容量が減らないのは、まさにこの現象です。対処法は、そのファイルを開いているプロセスを再起動することです(lsof | grep deletedで、削除済みなのに開いたままのファイルを特定できます)。

主な書き方一覧

dudfでよく使うオプションをまとめます。

書き方 働き
du -sh パス 指定パス以下の合計サイズ(読みやすい単位)
du -h --max-depth=1 1階層下までの内訳
du ... | sort -rh 容量の大きい順に並べる
df -h ファイルシステム全体の空き容量
Use% 使用率。100%に近いと危険
削除済みだが開いたままのファイル dfの容量は減らない(プロセス終了で解放)

よくある失敗

rmで消したのにdfの空きが増えない

そのファイルを開いたままのプロセスが残っている可能性があります。プロセスの再起動で解放されます。

duとdfの違いが分からず混同する

duはファイル・ディレクトリ単位、dfはファイルシステム全体です。役割が異なります。

-hを付けずに読みにくい数値のまま確認する

既定は1Kブロック単位で読みにくいです。-hを付けて確認します。

du --max-depth=1を付けず大量の内訳が出る

階層が深いディレクトリでは出力が膨大になります。--max-depthで絞り込みます。

単位付きの数値を通常のsortで並べようとする

11M1.1Mは通常のsortでは正しく並びません。sort -hを使います。

よくある質問

Qduとdfの違いは何ですか?
Aduは指定したファイルやディレクトリが使っている容量を調べるコマンドで、「どのフォルダが大きいか」を知りたいときに使います。dfはファイルシステム全体(マウントポイント単位)の空き容量を調べるコマンドで、「サーバー全体、あとどれくらい空いているか」を知りたいときに使います。見ている対象がまったく異なります。
Qファイルを削除したのにディスクの空き容量が増えません。
Aそのファイルをまだ開いているプロセスがある可能性が高いです。Linuxでは、rmはファイル名を消すだけで、プロセスが開いたままの実体はすぐには解放されません。実機でも、rm後もdfの使用量が変わらず、開いていた側を閉じると初めて容量が減ることを確認しています。該当プロセスを再起動すると解放されます。
Q容量を食っているディレクトリを見つけるには?
Adu -h --max-depth=1 パス | sort -rhという組み合わせが定番です。1階層下までの使用量を集計し、容量の大きい順に並べ替えます。sort -hを使うと、11M1.1Mのような単位付きの数値も正しく比較できます。
Qduやdfの表示が読みにくいです。
A-h(human-readable)オプションを付けてください。既定では1Kブロック単位の生の数値で表示されますが、-hを付けると460M251Gのような読みやすい単位に変換されます。実機でも、この違いを確認しています。
Q削除済みなのに開いたままのファイルを見つけるには?
Alsofコマンドで探せます。lsof | grep deletedのように実行すると、削除されたのにまだプロセスに開かれているファイルの一覧が表示されます。該当するプロセスを特定できれば、それを再起動することでディスク容量を解放できます。

まとめ

  • duファイル・ディレクトリ単位dfファイルシステム全体の容量を調べます。
  • 両方とも-hで読みやすい単位に。du --max-depth=1で階層を絞ります。
  • du ... | sort -rhで、容量の大きいディレクトリを素早く特定できます。
  • 削除済みでも開いたままのファイルは、dfの容量が減りません。プロセスの再起動で解放されます。

dudfは似た名前ですが役割が異なり、この違いを理解しておくと「ディスクがいっぱいなのに、大きなファイルが見当たらない」という不可解な状況にも落ち着いて対処できます。まずはdu -h --max-depth=1 | sort -rhで大きいディレクトリを特定し、それでも見つからないときはlsof | grep deletedを疑ってみてください。