「アクセス権が数値で表示されると、chmodの755と644のどちらか一目で判別できない」
そんなときに頼りになるのがstatコマンドです。ファイルサイズ・パーミッション(8進数と記号の両方)・タイムスタンプ3種類(Access / Modify / Change)・inode番号までをワンコマンドで表示してくれる、ファイル調査の定番ツールです。
この記事では、20年以上Linuxサーバーを運用してきた経験をもとに、statコマンドの基本的な使い方から、トラブル調査で必須となるタイムスタンプの読み方、inode番号でハードリンクを追跡するテクニックまで、実務で役立つ形でまとめて解説します。RHEL 9.4 / Ubuntu 24.04 LTSで動作確認済みです。
この記事のポイント
・stat ファイル名 でパーミッション・サイズ・3種のタイムスタンプを確認できる
・Access/Modify/Changeの違いを理解すれば障害調査が速くなる
・stat -c "%a %n" 等のフォーマット指定でスクリプト連携ができる
・inode番号を確認してハードリンクの同一性を判別できる
でも安心してください。プロのエンジニアはコマンドを暗記していません。
「現場で使える型」を効率よく使いこなしているだけです。
なぜstatコマンドを使うのか?(ls -lとの違い)
lsコマンドは一覧性に優れていますが、ファイル1つあたりの情報量は限られています。具体的には以下の点が不足しています。・パーミッションの8進数表記が出ない:ls -l では rw-r--r-- のような記号表記のみで、chmod で使う 644 のような数値形式が直接見えない
・タイムスタンプが1種類しか出ない:ls -l は通常 Modify time のみ。Access time や Change time は確認できない
・inode番号が省略される:-i オプションを付けない限り表示されない
・ブロックサイズや割り当て情報が見えない:実際のディスク占有量を確認できない
statコマンドはこれらを1つの出力にまとめてくれます。ファイルに起きた出来事を正確に追いたいとき、たとえば「このログファイルはいつ読まれたのか」「cronジョブがどこでファイルを書き換えたのか」といった調査で真価を発揮します。
ls コマンドとの使い分けを整理したい場合は、ls コマンドの基本オプションも合わせて確認してください。stat は深く1ファイルを調べる、ls は広く一覧する、という役割分担になります。
statコマンドの基本的な使い方
最も基本的な書式は次の通りです。ファイルパスを1つ以上指定するだけで、詳細情報が表示されます。1. 単一ファイルの情報を表示する
[admin@web01 ~]$ stat /etc/passwd File: /etc/passwd Size: 2547 Blocks: 8 IO Block: 4096 regular file Device: fd00h/64768d Inode: 33574977 Links: 1 Access: (0644/-rw-r--r--) Uid: ( 0/ root) Gid: ( 0/ root) Context: system_u:object_r:passwd_file_t:s0 Access: 2026-04-22 06:30:12.451239801 +0900 Modify: 2026-04-18 11:02:47.000000000 +0900 Change: 2026-04-18 11:02:47.834712019 +0900 Birth: 2026-03-01 09:00:00.000000000 +0900
・File:ファイルパス
・Size:バイト単位のファイルサイズ
・Blocks:割り当てブロック数(実際のディスク占有量の目安)
・IO Block:ファイルシステムのI/Oブロックサイズ(通常4096)
・Device:デバイス番号(fd00 = major 253, minor 0 など)
・Inode:inode番号。ファイル実体を指す一意のID
・Links:ハードリンクの数
・Access:パーミッション(8進数と記号の両方)
・Uid / Gid:所有者・グループ(数値とユーザー名)
・Context:SELinuxコンテキスト(SELinux有効時のみ)
・Access / Modify / Change / Birth:4種類のタイムスタンプ
2. 複数のファイルをまとめて確認する
ファイル名をスペース区切りで並べれば、複数ファイルを一度に調べられます。[admin@web01 ~]$ stat /etc/passwd /etc/shadow /etc/hosts
3. 簡易表示にする(-tオプション)
数値を1行にまとめた機械可読な出力にしたいときは -t(terse)を使います。[admin@web01 ~]$ stat -t /etc/passwd /etc/passwd 2547 8 81a4 0 0 fd00 33574977 1 0 0 1745289012 1745029367 1745029367 1740787200 4096 system_u:object_r:passwd_file_t:s0
タイムスタンプ3種類の違いを理解する
statコマンドの最大の価値は、タイムスタンプの違いを正確に見せてくれる点にあります。これが分かっていないと、障害調査で「いつ何が起きたか」を誤読してしまいます。Access(atime):最後にファイルを読んだ時刻
cat や less で中身を読んだとき、あるいはプログラムが open() してread() したときに更新されます。ただし、最近のディストリビューションでは relatime(読み込みごとには更新せず、1日1回程度に抑える)や noatime(更新しない)マウントオプションが既定のため、期待通りに動かない場合があります。atime に依存する運用(バックアップ対象の選別など)を組む場合は、マウントオプションの確認が必要です。詳しくはmount コマンドの使い方を参照してください。
Modify(mtime):ファイルの内容を最後に変更した時刻
書き込みが発生したタイミングで更新されます。ls -l で通常表示されるのはこの時刻です。「このログファイルに最後に書き込まれたのはいつか」を調べるときに使います。Change(ctime):メタデータが最後に変化した時刻
パーミッション変更(chmod)、所有者変更(chown)、リネーム、リンク数変化などで更新されます。mtime と違い、ユーザーが touch -d で任意の時刻に書き換えることができません。改ざん調査では ctime が最後の砦になります。Birth(crtime):ファイルの作成時刻
ext4(一部)・xfs・btrfs ではサポートされますが、ファイルシステムによっては取得できず「-」表示になります。古いext3 では出ません。実務での読み分け例
・Modify は新しいが Change も同じ時刻 → 通常の書き込み・Modify は古いが Change が新しい → 内容は変わっていないが権限や所有者が変わった
・Access だけ新しい → 誰かが読んだだけ
・Modify が未来時刻になっている → システム時刻ずれかtouch -t による改変の疑い
特に「Modify は古いのに Change は新しい」というパターンは、chmod/chown による意図しない権限変更を疑うサインです。ここに注意して見ていけば、障害対応の初動スピードが目に見えて変わります。私のセミナー受講生からも「サーバーが急に動かなくなった原因が chmod の事故だった」という報告を毎月のように聞きます。
【重要】ctime はユーザーが書き換える手段がありません。改ざん調査や不正変更の痕跡追跡では ctime を最優先で確認してください。
ディレクトリ・シンボリックリンクに対するstat
ディレクトリ情報を取得する
ディレクトリを指定すると、ディレクトリエントリ自身のメタデータが表示されます。ls -ld と似た目的ですが、inode 番号やタイムスタンプまで含めて確認できる点で上位互換です。[admin@web01 ~]$ stat /var/log File: /var/log Size: 4096 Blocks: 8 IO Block: 4096 directory Device: fd00h/64768d Inode: 67109889 Links: 16 Access: (0755/drwxr-xr-x) Uid: ( 0/ root) Gid: ( 0/ root)
シンボリックリンク:-Lで実体を追う
既定ではシンボリックリンク自身を表示しますが、-L(--dereference)を付けるとリンク先(実体)を表示します。# stat symlink itself [admin@web01 ~]$ stat /etc/localtime # stat dereferenced target [admin@web01 ~]$ stat -L /etc/localtime
-c / --formatでフォーマットを指定する
スクリプトで使うときは、必要な情報だけを取り出せる -c オプションが便利です。よく使う指定子は以下の通りです。・%n:ファイル名
・%s:サイズ(バイト)
・%a:パーミッション(8進数、例:644)
・%A:パーミッション(記号、例:-rw-r--r--)
・%U:所有者(ユーザー名)
・%G:所有グループ名
・%u / %g:UID / GID(数値)
・%i:inode番号
・%h:ハードリンク数
・%X / %Y / %Z:Access / Modify / Change の UNIXタイム
・%x / %y / %z:同、人間可読フォーマット
・%F:ファイル種別(regular file, directory, symbolic link など)
実用例1:パーミッションだけ一覧する
[admin@web01 ~]$ stat -c "%a %n" /etc/*.conf | head -5 644 /etc/chrony.conf 644 /etc/dnf.conf 644 /etc/host.conf 644 /etc/hosts.conf 600 /etc/krb5.conf
実用例2:権限が緩いファイルを検出する
# /etc 配下で others に書き込み権限があるファイルを検出 [admin@web01 ~]$ find /etc -type f -exec stat -c "%a %n" {} \; | awk '$1 ~ /[2367]$/'
実用例3:ファイルの更新時刻をUNIXタイムで取得する
# 1時間以内に更新されたか判定 [admin@web01 ~]$ mtime=$(stat -c %Y /var/log/messages) [admin@web01 ~]$ now=$(date +%s) [admin@web01 ~]$ echo $((now - mtime)) 542
inode番号で同一ファイルを見分ける
inode はファイルシステム上の実体を指すIDで、ハードリンクで複数のパス名を付けても inode は1つです。つまり 同じ inode = 同じ実体のファイルと判定できます。[admin@web01 ~]$ ln /tmp/original.txt /tmp/hardlink.txt [admin@web01 ~]$ stat -c "%i %n" /tmp/original.txt /tmp/hardlink.txt 1179648 /tmp/original.txt 1179648 /tmp/hardlink.txt
逆にシンボリックリンクの場合は inode が別になります。ハードリンクとシンボリックリンクを取り違えて運用事故になるケースは多いので、判別には stat -c "%i" が確実です。
トラブルシュート・よくあるエラー
「stat: cannot stat 'xxx': No such file or directory」
指定したファイルパスが存在しないか、現在のシェルの権限で到達できない場所にあります。typo のほか、シンボリックリンクの先が削除されている(broken symlink)場合も発生します。ls -la で同じパスを確認して原因を切り分けてください。「stat: cannot stat 'xxx': Permission denied」
ファイル自身への読み取り権限ではなく、上位ディレクトリの実行権限(x)が不足しています。ディレクトリの x はそのディレクトリを「通過する」権限なので、これが無いと配下のファイルに到達できません。ls -ld で上位ディレクトリの権限を順にたどって確認します。Birth が「-」になる
ファイルシステムが crtime に対応していないか、カーネルが古いためです。xfs や ext4(マウントオプションや作成時のパラメータに依存)なら取得できるケースが多いです。古い ext3 や tmpfs では取得できません。タイムスタンプが未来時刻になっている
3つのパターンを疑います。①システム時刻がずれている(chrony/ntpで同期確認)、②tar などで展開した際に元の mtime が保持された、③誰かが touch -t で意図的に変更した。時刻同期が合っているかは、まず date コマンドと hwclock --show を並べて確認します。本記事のまとめ
statコマンドは、ファイル1つを深く調べるための決定版ツールです。ls -l で「何か違和感がある」と感じたときに stat で掘り下げる、という使い分けを習慣にすると、トラブル対応のスピードが大きく変わります。| やりたいこと | コマンド |
|---|---|
| ファイルの詳細情報を確認する | stat /etc/passwd |
| 複数ファイルをまとめて確認する | stat /etc/passwd /etc/shadow |
| 機械可読な1行形式で出力する | stat -t /etc/passwd |
| シンボリックリンクの実体を確認する | stat -L /etc/localtime |
| パーミッションだけを抜き出す | stat -c "%a %n" /etc/*.conf |
| 更新時刻をUNIXタイムで取得する | stat -c %Y /var/log/messages |
| ファイルのinode番号を確認する | stat -c "%i %n" ファイル名 |
| ファイル種別を判定する | stat -c %F ファイル名 |
ファイル調査で毎回ネット検索に頼り、現場で一瞬固まっていませんか?
statコマンドの出力一つとっても、atime・mtime・ctimeの違いを押さえていなければ、障害の原因を読み違えて時間を浪費します。
ネットの切れ端の情報をコピペするだけでなく、現場で通用する安全なLinuxサーバー構築の「型」を体系的に身につけたい方へ、『Linuxサーバー構築入門マニュアル(図解60P)』を完全無料でプレゼントしています。
「独学の時間がもったいない」「プロから直接、現場の技術を最短で学びたい」という本気の方には、2日で実務レベルのスキルが身につく【初心者向けハンズオンセミナー】も開催しています。
3,100名以上が実践した「型」を無料で公開中
プロのエンジニアはコマンドを暗記していません。
「現場で使える型」を効率よく使いこなしているだけです。
その「型」を図解60Pにまとめた入門マニュアルを、完全無料でプレゼントしています。
登録10秒/合わなければ解除3秒 / 詳細はこちら

無料メルマガで学習を続ける
Linuxの実践スキルをメールで毎週お届け。
登録は1分、解除もいつでも可。
登録無料・いつでも解除できます