【Linux】ディスク容量の確認と調査手順|dfとduコマンドで容量逼迫の原因ファイルを特定する方法

コマンドリファレンス実務レシピ

サーバーのディスク使用率が100%近くに達し、「Disk Space Alert」の通知が鳴り響いたとき、インフラ運用担当者や開発者が最優先で行うべきは 「冷静かつ迅速な原因特定と安全な容量解放」 です。焦って適当なファイルを当てずっぽうに削除したり、無計画にディレクトリを手作業で巡回したりするのは非効率極まりなく、まさに「手作業は負け」です。

Linux環境において、ディスク容量トラブルの初動調査で必須となるのが 「全体の空き状況を把握する df コマンド」「ディレクトリやファイル単位の実使用量を調べる du コマンド」 の2大コマンドです。さらに sortfind をパイプラインで連携させることで、数万〜数十万のファイルの中から「容量を食い潰している真犯人ファイル」をわずか数秒で炙り出すことができます。

本記事では、ディスク容量調査の全体フローチャートから、df -hdf -i(inode枯渇)の正しい読み解き方、dusort を組み合わせた高速な掘り下げ調査手順、さらには実務で誰もが一度はハマる rm で削除したのに空き容量が増えない(lsof)」トラブルの解決策 や安全なログ切り詰め手順まで、現場で即座に役立つ実務ノウハウを完全網羅して解説します。

【結論】ディスク100%時にまず打つべき調査コマンド3行

  • 1. 全体の空き容量と逼迫パーティションを特定: df -h (inode枯渇の疑いがある場合は df -i
  • 2. カレント直下の容量TOP10を大きい順に表示: sudo du -sh .[!.]* * 2>/dev/null | sort -hr | head -n 10
  • 3. システム全体の500MB超の巨大ファイルを一発検索: sudo find / -xdev -type f -size +500M -exec ls -lh {} + 2>/dev/null | awk '{print $5, $9}' | sort -hr | head -n 20

ディスク容量調査の全体フロー(dfで全体把握 → duで犯人特定)

ディスク容量トラブルの調査において最も重要な原則は、「マクロからミクロへ(全体から詳細へ)」 の順序を徹底することです。最初からいきなり全ディレクトリの du を実行すると、ディスクI/Oが跳ね上がって高負荷な本番サーバーに致命的なトドメを刺すリスクがあります。

まずは df で「どのマウントポイント(パーティション)が溢れているのか」を素早く特定し、その配下に対してのみ du で段階的にドリルダウンしていくのがプロの鉄則です。

調査の流れを示すフローチャート

障害検知から原因ファイルの特定、容量解放までの標準的な一次切り分けフローは以下の通りです。

【ディスク逼迫調査の標準フロー】

  [アラート検知: ディスク使用率95%超]
                 │
                 ▼
  ┌────────────────────────────────────────┐
  │ 1. df -h で全体確認                    │
  │    ・どのマウントポイントが逼迫しているか? │
  │    ・/var, /home, / なのかを把握        │
  └──────────────────┬─────────────────────┘
                     │
         ┌───────────┴───────────┐
         ▼                       ▼
  [Use%が100%近い]        [Use%に余裕があるのに書けない]
         │                       │
         │                       ▼
         │               ┌─────────────────────────────────┐
         │               │ df -i で inode枯渇を確認        │
         │               │ ・IUse%が100%なら小ファイル群特定│
         │               └─────────────────────────────────┘
         ▼
  ┌────────────────────────────────────────┐
  │ 2. 原因ディレクトリへ移動し du で調査  │
  │    du -sh .[!.]* * | sort -hr | head   │
  │    ・上位の肥大化ディレクトリを特定   │
  └──────────────────┬─────────────────────┘
                     │ (階層を一段ずつ掘り下げ)
                     ▼
  ┌────────────────────────────────────────┐
  │ 3. 原因ファイルを特定                  │
  │    ・巨大なログ(/var/log)            │
  │    ・放置されたコアダンプやバックアップ│
  └──────────────────┬─────────────────────┘
                     │
         ┌───────────┴───────────┐
         ▼                       ▼
  [通常ファイル]          [rmしたのに容量が増えない]
         │                       │
         ▼                       ▼
  ┌─────────────────┐    ┌─────────────────────────────────┐
  │ 安全に切り詰め   │    │ lsof | grep deleted で特定      │
  │  > logfile      │    │ プロセス再起動でFDを解放        │
  └─────────────────┘    └─────────────────────────────────┘

このフローを頭に入れておくことで、障害発生時でも慌てず無駄のない初動対応が可能になります。

全体の空き容量を確認する(dfコマンド)

df(Disk Free)コマンドは、Linuxシステムにマウントされている各ファイルシステムの 総容量・使用量・空き容量・使用率・マウント先 を瞬時に一覧表示するコマンドです。ファイル1つひとつを走査するのではなく、ファイルシステムのスーパーブロックからメタデータを直接読み取るため、ファイル数にかかわらず 「一瞬(ミリ秒単位)」 で結果が返るのが最大の特徴です。

基本書式: df -h(人間が読みやすい単位で表示)

オプションなしで df を実行すると、1KB(1024バイト)ブロック単位で数値が表示され、桁数が多すぎて直感的に把握できません。実務では必ず -h(–human-readable) オプションを付けて実行します。

# 人間が読みやすい単位(G=ギガバイト, M=メガバイト)で表示
df -h

# 実務でのおすすめ: ファイルシステムの種類(ext4, xfs等)も同時に表示
df -hT

# 仮想ファイルシステム(tmpfs, devtmpfsなど)を除外して物理ディスクのみ表示
df -hT -x tmpfs -x devtmpfs

物理ディスクのみに絞り込む -x tmpfs を併用すると、コンテナ環境やクラウドサーバーでもノイズが消えて一気に視認性が高まります。

出力項目の見方(Filesystem, Size, Used, Avail, Use%, Mounted on)

df -h の実行結果として得られる各カラムの意味と、障害対応時に注目すべき判断基準を整理しました。

カラム名 表示例 意味と実務でのチェックポイント
Filesystem /dev/nvme0n1p1 ディスクのデバイス名または論理ボリューム名(LVMなど)。物理障害の切り分けに利用。
Size 50G ファイルシステム全体の総容量。
Used 46G 現在データが書き込まれている実使用量。
Avail 1.5G 一般ユーザーが書き込み可能な「残りの空き容量」。
Use% 97% ディスク使用率。90%超で警告、95%超で緊急対応 が運用保守の一般的基準。
Mounted on //var そのファイルシステムが結合されているディレクトリパス。調査対象の絞り込みに必須。

ここで実務エンジニアが覚えておくべき重要ポイントがあります。それは、「Size(50G)から Used(46G)を引いても、Avail(1.5G)と一致しない(2.5G足りない)」 という現象です。

これは ext4 などの標準的なLinuxファイルシステムにおいて、「rootユーザー専用の予約領域(デフォルトで全体の約5%)」 が確保されているためです。一般ユーザーの書き込みが100%(Availが0)になっても、rootによるSSHログインやシステムデーモンの最低限の動作を破綻させないための安全設計です。

容量はあるのにファイルが作れない?inode枯渇の確認(df -i)

df -h で見ると空き容量が何十GBもあるのに、新規ファイルを保存しようとすると No space left on device エラーが出る」という不可解なトラブルに遭遇したことはありませんか?

その原因の9割は 「inode(インデックスノード)の枯渇」 です。Linuxでは、ファイルサイズとは別に「作成可能なファイルやディレクトリの総数(inode数)」がファイルシステム作成時にあらかじめ上限として決められています。サイズがわずか数バイトの極小ファイルでも、1つ作れば1つのinodeを消費します。

# inode使用状況を確認するコマンド
df -i

実行結果の例:

Filesystem      Inodes   IUsed   IFree IUse% Mounted on
/dev/nvme0n1p1  3276800 3276800       0  100% /
tmpfs           2048000       1 2047999    1% /dev/shm

上記のように IUse% が 100%(IFreeが0) になっていると、ディスクのギガバイト容量がどれだけ余っていても1つも新しいファイルを作成できなくなります。

inode枯渇を招く代表的な犯人は以下の通りです:

  • PHPやWebフレームワークの セッションファイル(数十万個の小ファイル)/var/lib/php/sessions に残留している
  • メール送信サーバーの スプール・キュー(不達メールの山)/var/spool/postfix/maildrop に溜まっている
  • キャッシュや一時ファイル(/tmp/var/cache)が定期クリーンアップされていない

どのディレクトリがinodeを大量消費しているか特定したい場合は、以下のワンライナーでファイル数TOP10ディレクトリを調査できます。

# カレントディレクトリ直下の各ディレクトリに含まれるファイル数をカウントして降順ソート
sudo find . -xdev -type f | cut -d "/" -f 2 | sort | uniq -c | sort -nr | head -n 10

ディレクトリ・ファイルのサイズを調査する(duコマンド)

df で逼迫しているマウントポイントを特定したら、次は du(Disk Usage)コマンド の出番です。du は指定したディレクトリ配下のファイルやサブディレクトリを再帰的に巡回し、実際に占有されているブロックサイズを集計します。

指定ディレクトリの総サイズを確認する(du -sh /path)

特定ディレクトリ全体の合計サイズだけをサッと知りたいときは、-s(–summarize)-h(–human-readable) を組み合わせます。

# /var ディレクトリ全体の合計サイズを確認
sudo du -sh /var

# 実行結果例:
# 28G    /var

-s オプションを付けないと、配下の全サブディレクトリの行が画面に延々と出力されてしまうため、「特定ディレクトリの合計を見たいときは必ず -s を付ける」 と覚えておきましょう。

また、システムディレクトリを一般ユーザー権限で走査すると Permission denied のエラーが大量に出力されて結果が埋もれてしまいます。必ず sudo を付けるか、2>/dev/null で標準エラー出力を破棄するのが実務の定石です。

カレントディレクトリ直下のサイズを一覧表示する(du -sh * または du -h –max-depth=1)

容量を食っているディレクトリを突き止める際は、カレントディレクトリ直下の子ディレクトリ群のサイズを一覧比較します。実務では以下の2つの記法がよく使われます。

# パターン1: ワイルドカード(*)で直下の一覧を表示
sudo du -sh * 2>/dev/null

# パターン2: --max-depth=1 オプションで1階層目のみを指定(推奨)
sudo du -h --max-depth=1 . 2>/dev/null

ここで注意すべき実務の落とし穴が 「隠しファイル・隠しディレクトリ(ドットファイル)」 の扱いです。

シェル標準のワイルドカード * では、.cache.docker.git などのドットで始まる隠しファイルがマッチしません。「du -sh * で合計しても全体のサイズと合わない」という場合は、隠しディレクトリが数十GBを消費しているケースが多々あります。

隠しファイルも漏れなく含めて集計したい場合は、--max-depth=1 を使用するか、Bashのパターン .[!.]* * を指定してください。

# 隠しファイルも含めてカレント直下を漏れなく集計する実務コマンド
sudo du -sh .[!.]* * 2>/dev/null

サイズが大きい順に並び替える(du -sh * | sort -hr | head -n 10)

du の出力結果はディレクトリの並び順(通常はファイル名順や走査順)であり、サイズ順には並んでいません。数十個のディレクトリから大容量のものを探すには、パイプライン( | )を使って sort -hrhead を繋ぎます。

# カレント直下の容量を大きい順に上位10件表示(最強の調査ワンライナー)
sudo du -sh .[!.]* * 2>/dev/null | sort -hr | head -n 10

実行結果の例:

18G    /var/log
6.2G   /var/lib
2.1G   /var/www
450M   /var/cache
120M   /var/backups
15M    /var/spool
4.0K   /var/tmp

このパイプラインの重要ポイントは sort コマンドの -h オプション です。

  • -n(数値ソート)を使うと、「18G」「6.2G」「450M」という単位混在を正しく解釈できず、450M18G よりも大きいと誤判定されてしまいます。
  • -h(–human-numeric-sort) を指定することで、K(キロ)、M(メガ)、G(ギガ)、T(テラ)の単位を正しく認識して降順(-r)に並び替えてくれます。

上記の結果から /var/log が 18GB を占有していることが判明したら、次は cd /var/log で移動し、再度同じコマンドを実行します。このように du | sort | head → 最上位へ cd を繰り返すことで、わずか数分で真犯人のファイルにたどり着くことができます。

ディスク逼迫時の実務対処とよくある落とし穴

原因ファイルを特定できても、安易に rm コマンドを実行するとシステム停止やさらなる障害を引き起こす危険があります。ここからは実務現場で必須となる安全な対処テクニックと落とし穴を解説します。

巨大なログファイル(/var/log)の確認と安全な切り詰め方法(> logfile)

ディスク逼迫の原因として最も多いのが、Webサーバー(Nginx/Apache)のアクセスログや、アプリケーションのエラーログが肥大化して数十GBに達しているケースです。

このとき、絶対にやってはいけないNG操作が「稼働中プロセスのログファイルを rm で削除すること」 です。実行中のプロセスがログファイルを開いたままの場合、削除しても容量が解放されないばかりか、ログの追記が行われなくなって調査が困難になります。

安全かつ即座に空き容量を回復させるには、ファイルを削除せず中身だけを空(0バイト)にする 「ヌルリダイレクト(切り詰め)」 を使います。

# 危険なNG操作(プロセス稼働中に実行してはいけない)
# rm /var/log/nginx/access.log

# 推奨: ヌルリダイレクトによる安全な即時切り詰め(0バイト化)
sudo truncate -s 0 /var/log/nginx/access.log

# またはリダイレクト構文を使用
sudo sh -c '> /var/log/nginx/access.log'

truncate -s 0> logfile を使えば、ファイルシステムのinode番号やファイルのパーミッションを保持したままサイズだけを一瞬で0にできます。実行中のデーモンも何事もなかったかのようにログ書き込みを継続できます。

なお、ログファイル肥大化の再発を恒久的に防ぐためには、logrotate による日次ローテーションと圧縮設定が不可欠です。詳しい設定手順については関連記事 logrotate設定ファイルの書き方|圧縮・テスト実行・ログ溢れ防止 を併せてご確認ください。

rmで削除したのにdfの空き容量が増えない原因(プロセスがファイルを掴んでいる/lsof | grep deleted)

rm コマンドで20GBのログファイルを削除したのに、df -h で確認しても空き容量が1バイトも増えない!」——これはインフラ運用現場で非常によくあるトラブルです。

なぜこの現象が起きるのでしょうか?Linuxのファイルシステムでは、ファイルを rm しても 「ディレクトリエントリ(ファイル名とinodeの紐付け)が解除されただけ」 に過ぎません。もし他のプロセスがそのファイルをオープンし続けている場合(ファイルディスクリプタを保持している場合)、OSはディスクブロックの解放を保留します。

この「削除されたのに掴まれたままのファイル」を炙り出すのが lsof(List Open Files)コマンド です。

# プロセスに掴まれたままの削除済みファイルを一覧表示
sudo lsof | grep '(deleted)'

# またはリンク数が0のファイルをピンポイント抽出
sudo lsof +L1

出力結果の例:

COMMAND   PID USER   FD   TYPE DEVICE   SIZE/OFF NODE NAME
nginx    1234 root    7w   REG  259,1 21474836480  5678 /var/log/nginx/access.log (deleted)

上記では、PID 1234 の Nginx が access.log(約20GB)を掴んだまま稼働していることが一目瞭然です。

この状態から容量を解放する手順は以下の2通りです:

  1. プロセスの再起動・リロード(正攻法):
    sudo systemctl reload nginx
    # または
    sudo systemctl restart nginx

    プロセスが再起動してファイルディスクリプタを閉じた瞬間に、OSによってディスクブロックが即時解放され、df -h の空き容量が回復します。

  2. プロセスを停止できない場合の緊急解放テクニック:
    本番環境の都合でサービスを再起動できない場合は、/proc ファイルシステムを経由して直接ファイルディスクリプタを切り詰めます。

    # /proc/[PID]/fd/[FD番号] に対して空文字をリダイレクト
    sudo sh -c '> /proc/1234/fd/7'

    これでサービスを無停止のまま、掴まれたままの容量を0バイトに解放できます。まさに現場のプロが使う救命テクニックです。

コマンド一発!ディスク使用量TOP20ファイルを検索する(find / -type f -size +500M)

「階層を1つずつ du で掘り下げる時間すらない」「とにかくシステム全体のどこかに潜んでいる超巨大なファイルを一撃で特定したい」というときは、find コマンドの -size オプション を活用します。

# 500MB以上の巨大ファイルをシステム全体から検索してサイズ順にTOP20を表示
sudo find / -xdev -type f -size +500M -exec ls -lh {} + 2>/dev/null | awk '{print $5, $9}' | sort -hr | head -n 20

このワンライナーには実務の安全設計が凝縮されています:

  • -xdev(または -mount: 別ファイルシステム(NFSや /proc、外付けストレージなど)に跨がらず、対象のパーティション内だけを走査します。これがないとネットワーク共有フォルダまで走査してフリーズする恐れがあります。
  • -type f: ディレクトリやデバイスファイルを除外し、通常ファイルのみを対象にします。
  • -size +500M: 500MBを超えるファイルのみに限定することで、検索速度と出力精度を大幅に高めます。
  • 2>/dev/null: 権限不足のエラー出力を抑制します。

さらに、「ここ1〜2日で急激に肥大化したファイル」を突き止めたい場合は、更新日時(-mtime)を組み合わせると効果的です。

# 直近24時間以内(-mtime -1)に更新された100MB以上の巨大ファイルを検索
sudo find /var/log -xdev -type f -size +100M -mtime -1 -exec ls -lh {} + 2>/dev/null

ファイル検索や条件指定の高度なテクニックについては、関連記事 【Linux】findコマンドの使い方完全ガイド および 【Linux】sortとuniqコマンドの使い方 もぜひご参照ください。

まとめ & 関連記事

Linuxサーバーのディスク容量逼迫トラブルは、正しい手順とコマンドさえ知っていれば、数分で原因を突き止めて安全に対処できます。本記事の要点を振り返りましょう。

ディスク容量調査・対処の3大原則

  • 1. 調査は「マクロからミクロへ」: まず df -h で全体と逼迫パーティションを把握し、inode枯渇(df -i)も確認した上で、du -sh .[!.]* * | sort -hr で段階的に掘り下げる。
  • 2. 稼働中ログの削除は厳禁: 動作中のログは rm せず、truncate -s 0 logfile> logfile で安全に中身を切り詰める。
  • 3. rm後に空き容量が増えない時は lsof: プロセスが掴んでいる削除済みファイルを sudo lsof | grep deleted で特定し、プロセスのリロードや /proc/[PID]/fd/ へのリダイレクトで解放する。

あわせて読みたい関連記事

ディスク管理やテキスト処理、ログ運用の自動化をさらに深めたい方は、以下の実務ガイドもぜひチェックしてみてください。

【Linux】freeコマンドの見方とメモリ使用率の確認|availableとfreeの違い・buff/cacheの意味を徹底解説

ディスク容量と並ぶ最重要リソース「メモリ」の確認手順を解説。freeとavailableの決定的な違い、実質使用率の計算式、スワップスラッシング時の調査手順まで完全網羅。

logrotate設定ファイルの書き方|圧縮・テスト実行・ログ溢れ防止

ログファイルの自動ローテーション、gzip圧縮、古いログの世代管理を体系的に解説。ディスク満杯を未然に防ぐ必須知識。

【Linux】findコマンドの使い方完全ガイド|ファイル名・階層・日時検索から一括処理まで

サイズ指定(-size)だけでなく、更新日時(-mtime)やパーミッションによる検索、-execによる安全なバッチ処理を網羅。

【Linux】sortとuniqコマンドの使い方|重複削除・出現回数カウント・数値並び替えのパイプライン実践

sort -hr による人間可読ソートの原理や、重複削除・カウント集計の実務パイプラインパターンを詳しく解説。

df コマンドの使い方|ディスク使用量・空き容量とinodeの確認方法

df コマンドの全オプション、ファイルシステムごとの挙動差、root予約領域の仕組みをより詳細に知りたい方向けのリファレンス。

du コマンドの使い方|ディレクトリ別容量調査と大容量ファイル特定

du コマンドの各種オプション(-a, -c, -L等)や、ファイルシステム境界(-x)の安全制御を深掘りしたリファレンス記事。

Bash玄

はじめまして!Bash玄です。

エンジニアとしてシステム運用に携わる中で、手作業の多さに限界を感じ、Bashスクリプトを活用して業務を効率化したのがきっかけで、この道に入りました。「手作業は負け」「スクリプトはシンプルに」をモットーに、誰でも実践できるBashスクリプトの書き方を発信しています。

このサイトでは、Bashの基礎から実践的なスクリプト作成まで、初心者でもわかりやすく解説しています。少しでも「Bashって便利だな」と思ってもらえたら嬉しいです!

# 好きなこと
- シンプルなコードを書くこと
- コマンドラインを快適にカスタマイズすること
- 自動化で時間を生み出すこと

# このサイトを読んでほしい人
- Bashに興味があるけど、何から始めればいいかわからない人
- 定型業務を自動化したい人
- 効率よくターミナルを使いこなしたい人

Bashの世界に一歩踏み出して、一緒に「Bash道」を極めていきましょう!

Bash玄をフォローする

コメント