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が最もよく使う形です。
# 指定ディレクトリの合計サイズ(-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オプションは、10Mや1.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 -rhで11Mのディレクトリが1.1Mのディレクトリより上に正しく並びました。通常のsort -nは数値専用で、単位付きの文字列(11Mなど)は正しく並び替えられませんが、sortの-h(human-numeric-sort)を使えばこの問題を回避できます。「サーバーの容量を圧迫しているディレクトリ・トップ5」を調べたいときの定番の組み合わせです。
dfの基本:ファイルシステム全体の空き容量
dfはduとは違い、マウントされているファイルシステム全体の使用量・空き容量を表示します。「サーバー全体、あとどれくらい空いているか」を調べるコマンドです。
# 見やすい単位(-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を付けると251G・460Mのような読みやすい単位で表示され、付けないと1Kブロック単位の生の数値(263112772など)で表示されて非常に読みにくいことを確認しました。duと同様、dfもほぼ常に-hを付けて使うと考えてよいでしょう。Use%列が100%に近づいたら要注意のサインです。
【最重要】削除したのに容量が減らない罠
duとdfの違いが最も強烈に表れるのがこの現象です。ファイルを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分、解放された)
実機で、20MBのファイルを作成し、ファイルディスクリプタで開いたままrmで削除したところ、lsでは「存在しない」扱いになり、duの集計からも消えました。しかしdfの使用量はrmの前後でまったく変わりませんでした(488188KBのまま)。そしてそのファイルを開いていた側(プロセスやファイルディスクリプタ)を閉じた瞬間、dfの使用量が約20MB分(20480KB)減少し、削除したファイルのサイズとぴったり一致しました。Linuxでは、ファイルの実体は「開いているプロセスが0個になって初めて」本当に削除されます。rmはディレクトリからの「名前」を消すだけで、実体(inode)はまだ誰かが参照していれば残るのです。ログファイルを大きくしたまま長時間動いているプロセス(Webサーバーなど)をrmしても容量が減らないのは、まさにこの現象です。対処法は、そのファイルを開いているプロセスを再起動することです(lsof | grep deletedで、削除済みなのに開いたままのファイルを特定できます)。
主な書き方一覧
du・dfでよく使うオプションをまとめます。
| 書き方 | 働き |
|---|---|
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で並べようとする
11Mと1.1Mは通常のsortでは正しく並びません。sort -hを使います。
よくある質問
duは指定したファイルやディレクトリが使っている容量を調べるコマンドで、「どのフォルダが大きいか」を知りたいときに使います。dfはファイルシステム全体(マウントポイント単位)の空き容量を調べるコマンドで、「サーバー全体、あとどれくらい空いているか」を知りたいときに使います。見ている対象がまったく異なります。rmはファイル名を消すだけで、プロセスが開いたままの実体はすぐには解放されません。実機でも、rm後もdfの使用量が変わらず、開いていた側を閉じると初めて容量が減ることを確認しています。該当プロセスを再起動すると解放されます。du -h --max-depth=1 パス | sort -rhという組み合わせが定番です。1階層下までの使用量を集計し、容量の大きい順に並べ替えます。sort -hを使うと、11Mや1.1Mのような単位付きの数値も正しく比較できます。-h(human-readable)オプションを付けてください。既定では1Kブロック単位の生の数値で表示されますが、-hを付けると460Mや251Gのような読みやすい単位に変換されます。実機でも、この違いを確認しています。lsofコマンドで探せます。lsof | grep deletedのように実行すると、削除されたのにまだプロセスに開かれているファイルの一覧が表示されます。該当するプロセスを特定できれば、それを再起動することでディスク容量を解放できます。まとめ
duはファイル・ディレクトリ単位、dfはファイルシステム全体の容量を調べます。- 両方とも
-hで読みやすい単位に。du --max-depth=1で階層を絞ります。 du ... | sort -rhで、容量の大きいディレクトリを素早く特定できます。- 削除済みでも開いたままのファイルは、dfの容量が減りません。プロセスの再起動で解放されます。
duとdfは似た名前ですが役割が異なり、この違いを理解しておくと「ディスクがいっぱいなのに、大きなファイルが見当たらない」という不可解な状況にも落ち着いて対処できます。まずはdu -h --max-depth=1 | sort -rhで大きいディレクトリを特定し、それでも見つからないときはlsof | grep deletedを疑ってみてください。
- grep(文字列検索)
- find(ファイル検索)
- sed(置換・行編集)
- awk(列抽出・集計)
- chmod(パーミッション)
- tar(圧縮・解凍)
- リダイレクトとパイプ
- ps・kill(プロセス管理)
- 環境変数とPATH
- ln(シンボリックリンク)
- cp・mv・rm(コピー/移動/削除)
- history(コマンド履歴)
- curl(HTTP通信・API)
- jq(JSON処理)
- vim(基本操作・終了方法)
- cron・crontab(定期実行)
- sort・uniq・wc(並べ替え/集計)
- xargs(一括処理)
- chown・chgrp(所有者/グループ変更)
- diff(ファイル比較)
- du・df(ディスク使用量)
- よく使うコマンドまとめ
- cd(ディレクトリ移動)
