Linuxで「ファイルのブロック数」を確認するときは、ls -s、stat、duがそれぞれ何を表すかを分けて考える必要があります。ファイルの論理サイズ、ファイルに割り当てられた領域、コマンドが見やすく換算した表示単位は同じものではありません。本稿ではGNU coreutilsを前提に、日常確認から容量調査、自動集計までを読み取り専用の例で整理します。
最初に押さえる3つの数値
最も重要なのは、バイト単位の論理サイズと、ストレージ上の割り当て量を混同しないことです。ls -lやstatの%sは通常、ファイル末尾までの論理的な長さをバイトで示します。一方、ls -sやstatの%bは、ファイルに割り当てられた領域に関係する値です。小さいファイルでは割り当て単位の都合で論理サイズより大きくなり、スパースファイルでは逆に小さくなることがあります。
さらに「ブロック」という語には、コマンドの表示単位、statが返す割り当てブロック、効率的なI/Oの推奨サイズ、ファイルシステム内部の割り当て単位という複数の意味があります。数値だけを記録すると、どの意味か分からなくなります。報告書や監視ログには、コマンド、オプション、単位、対象パス、実行日時、対象ファイルシステムを一緒に残すのが確実です。
ls -sで割り当て量を手早く表示する
ls -sは各ファイル名の左にファイルシステム割り当て量を表示します。GNU lsでは通常1024バイト単位ですが、環境変数やオプションで変わり得ます。人が端末で比較するだけなら-hが便利ですが、後で数値処理するなら--block-sizeを明示し、同じ条件で採取します。--は、それ以降をオプションではなくファイル名として扱わせるための区切りです。
ls -s --block-size=1K -- /var/log/syslog
ls -sh -- /var/log/syslog
ls -ls --block-size=1K -- /var/log/syslog
1行目はKiB相当の固定単位、2行目は人が読みやすい単位、3行目は割り当て量に加えてリンク数、所有者、論理サイズ、更新日時も確認する例です。ls -lのサイズ欄と、-sで追加される左端の数値は意味が違います。ディレクトリを引数にした場合は中身の一覧になるため、ディレクトリエントリ自身だけを確認したい場合は-dを併用します。
statでブロック数と単位を明示する
機械的な記録にはstatが向いています。GNU statのファイル用書式では、%sが総バイト数、%bが割り当て済みブロック数、%Bが%b1個当たりのバイト数、%oが最適I/O転送サイズです。割り当て量の概算は%bと%Bを掛けた値ですが、%oを掛けるわけではありません。
stat --format='name=%n size_bytes=%s allocated_blocks=%b bytes_per_block=%B io_hint=%o' -- /var/log/syslog
stat --printf='%n\t%s\t%b\t%B\n' -- /var/log/syslog
--formatは各対象の後に改行を付け、--printfでは改行を自分で指定します。パスに空白があっても、引数を引用して--を置けば安全に一件を確認できます。シェルで乗算する場合は、値を検証したうえで算術展開しますが、大量ファイルや非常に大きい値では桁あふれや解析ミスを避けるため、元の%bと%Bも保存しておくと再計算できます。
表示ブロックサイズは実ディスクのブロックサイズではない
GNU coreutilsのdf、du、lsが表示する「ブロック」は、読みやすく換算するための単位です。LS_BLOCK_SIZE、BLOCK_SIZE、BLOCKSIZE、POSIXLY_CORRECTなどの環境変数によって既定値が変化します。したがって、別サーバーのls -s結果をそのまま比較すると、同じ数字でも単位が異なる可能性があります。
再現性を優先するなら、端末の環境に依存させず--block-size=1K、--block-size=1M、または--block-size=1を指定します。1Kは1024バイト、1kBは1000バイトなので、K、KiB、kBの表記も記録します。人向けの-hは便利ですが、丸めが入るため閾値判定や差分計算の入力には固定単位かstatの生値を使います。
スパースファイルでは論理サイズより割り当て量が小さい
スパースファイルは、ゼロが連続する領域などを実ブロックとして保持せず「穴」として表現できます。そのため、statの%sが数GiBでも、%bと%Bから分かる割り当て量は小さい場合があります。バックアップイメージ、仮想ディスク、データベース用ファイルを調べるとき、論理サイズだけで容量を見積もると誤差が大きくなります。
逆に、非常に小さい通常ファイルは、データ以外の管理情報や割り当て単位の都合で、論理サイズより多くの領域を使うことがあります。ただし、圧縮、コピーオンライト、重複排除、共有エクステント、ネットワークファイルシステムでは、OSから見える割り当て値と物理デバイス上の消費量が一致しない場合があります。duも絶対的な物理消費量ではなく、OSが報告する情報に基づく推定として扱います。
duでファイルやディレクトリの使用量を比較する
duは、指定したファイル集合を表現するために必要な領域を集計します。通常モードは割り当て量、--apparent-sizeは論理的な見かけのサイズです。両方を同じ固定単位で出すと、スパース性や小さいファイルの多さを把握しやすくなります。ディレクトリ配下を調査するときは、別マウントへ横断しない-xと深さ制限を使うと対象範囲を管理できます。
du --block-size=1K -- /var/log/syslog
du --apparent-size --block-size=1K -- /var/log/syslog
du -x --max-depth=1 --block-size=1M -- /var/log
duは同じinodeへの複数のハードリンクを通常一度だけ数えますが、lsのディレクトリ合計や個別一覧とは集計規則が異なります。また、権限不足で読めないディレクトリがあると結果が不完全になります。標準エラーを見えなくせず、終了ステータスとエラーメッセージを確認してから集計値を採用します。管理者権限は調査範囲と必要性を確認してから使用します。
複数ファイルを安全に調査する
ファイル名には空白、タブ、改行、先頭のハイフンを含められます。lsの見た目を空白で分割する方法は、自動処理に不向きです。GNU環境で複数ファイルの属性を採取するなら、findの-exec ... {} +でパスを引数として渡し、stat側で区切りを設計します。まず狭い読み取り専用ディレクトリで件数と出力形式を確認します。
find /var/log/myapp -xdev -type f -exec stat --printf='%d\t%i\t%s\t%b\t%B\t%n\n' -- {} +
この例はデバイス番号、inode番号、論理バイト数、割り当てブロック数、1ブロック当たりのバイト数、名前を出します。ただし改行を含むファイル名まで厳密に機械処理するなら、改行区切りではなくNUL区切りを設計し、受け側もNUL対応にします。調査対象が変化している最中は取得値も変わるため、単一時点の完全なスナップショットではない点にも注意します。
容量不足の原因を切り分ける手順
- 対象ファイルがどのマウントポイントに属するかを確認し、別ファイルシステムの値を混ぜない。
statで論理サイズ、割り当てブロック、ブロック単位、inode、リンク数を同時に記録する。duの通常値と--apparent-sizeを固定単位で比較する。- 多数の小さいファイルが疑われる場合は、ブロック使用量だけでなくinode使用量も調べる。
- 圧縮やコピーオンライトを使うファイルシステムでは、専用の公式ツールが示す物理使用量も確認する。
- 権限エラー、ファイルの増減、別マウントの横断、ハードリンクの数え方を結果と一緒に記録する。
ブロック数の確認は、コマンドを一つ覚えるより「どの層の容量を測っているか」を明示することが重要です。端末での即時確認はls -s、属性の厳密な採取はstat、ディレクトリ単位の集計はduと役割を分けると、容量報告の食い違いを説明しやすくなります。
確認チェックリスト
- 論理サイズと割り当て量を別の列として扱っている
--block-sizeまたは%Bで単位を明記しているstatのI/O推奨サイズと割り当てブロック単位を混同していない- スパース、圧縮、コピーオンライト、ハードリンクの影響を考慮している
- 対象パスを引用し、先頭ハイフン対策として
--を使っている - 権限エラーと終了ステータスを確認している

コメント