stat入門|ファイルの詳細情報とタイムスタンプを読む基本

stat入門|ファイルの詳細情報とタイムスタンプを読む基本

「このファイル、最後にいじったのはいつだったか」。運用中のサーバーで、そう振り返りたくなる場面がときどきあります。

ところが ls -l の1行では、サイズと更新日時までしか分かりません。

権限をいつ書き換えたのかまで追いたくなったとき、私が手を伸ばすのが stat という小さなコマンドでした。

statは「ls -l の詳しい版」

stat は、ファイルやディレクトリのメタ情報をまとめて表示するコマンドです。

パスを渡すだけで、サイズ・inode 番号・パーミッション・所有者・各種タイムスタンプが一気に並びます。

$ stat note.txt
  File: note.txt
  Size: 6	Blocks: 8	IO Block: 4096	regular file
Device: 801h/2049d	Inode: 21364	Links: 1
Access: (0644/-rw-r--r--)  Uid: (1470/kamome)   Gid: (1470/kamome)
Access: 2026-08-08 20:54:15.431031927 +0900
Modify: 2026-08-08 20:54:15.431031927 +0900
Change: 2026-08-08 20:54:15.436031927 +0900
 Birth: 2026-08-08 20:54:15.431031927 +0900

この記事の出力は、すべて Ubuntu 22.04 の GNU coreutils 8.32 で実際に叩いて確かめたものです。

注目したいのは、下4行に並んだ Access / Modify / Change / Birth という時刻。

ls -l が見せてくれるのは、このうち Modify のひとつだけでした。

4つの時刻を読み分ける

4つの時刻は、それぞれ動く条件が違います。

  • Access(atime):中身を最後に読んだ時刻
  • Modify(mtime):中身を最後に書き換えた時刻。ls -l に出るのはこれ
  • Change(ctime):メタ情報が最後に変わった時刻
  • Birth:作成時刻。ファイルシステムが対応していれば表示される

いちばんの落とし穴は、ctime の C が Create ではなく Change を指しているという点。

中身をまったく触らず権限だけ変えても、ctime は動きます。

$ chmod 600 note.txt
$ stat -c 'atime=%x' note.txt
atime=2026-08-08 20:54:24.376031964 +0900
$ stat -c 'mtime=%y' note.txt
mtime=2026-08-08 20:54:25.580031969 +0900
$ stat -c 'ctime=%z' note.txt
ctime=2026-08-08 20:54:26.783031974 +0900

chmod を1回打っただけで Change の秒数だけが進み、Access と Modify は据え置きのままでした。

「中身は変えていないのに更新されている」と見えるときは、たいていメタ情報のほうが動いています。

atime は読むたびには更新されない

読み取りのたびに atime を書き戻すとディスクへの書き込みが増えるため、最近のディストリビューションは relatime という設定でマウントされているのが普通です。

relatime では、atime が mtime より古いときと、前回の更新から1日以上経ったときにしか atime を更新しません。

$ cat note.txt > /dev/null   # 1回目
$ stat -c '%x' note.txt
2026-08-08 20:54:39.578032027 +0900
$ cat note.txt > /dev/null   # 2回目
$ stat -c '%x' note.txt
2026-08-08 20:54:39.578032027 +0900   # 動かない

読んだのに atime が変わらないのは壊れているからではなく、こういう仕組みだからでした。

-c で欲しい値だけ取り出す

スクリプトに組み込むなら、全項目を表示させる必要はありません。

-c に書式を渡すと、指定した項目だけを1行で返してくれます。

$ stat -c '%s %n' *.txt
12 hard.txt
8 link.txt
12 note.txt

よく使う指定子は、このあたりに絞られます。

  • %n:ファイル名/%s:サイズ(バイト)
  • %A:権限の記号表記/%a:8進表記
  • %U:所有者/%i:inode 番号/%h:ハードリンク数
  • %F:種別(regular file・directory・symbolic link)
  • %y:mtime/%Y:mtime のエポック秒

なかでも %Y はエポック秒で返るので、シェルの数値比較にそのまま流し込めます

$ stat -c '%Y %n' note.txt
1786190065 note.txt

リンクの正体を見抜く

stat がとりわけ効いてくるのは、リンクを扱うときでした。

stat は既定でシンボリックリンク自身を見にいき、-L を付けるとリンク先を見にいきます。

$ stat -c '%N %F' link.txt
'link.txt' -> 'note.txt' symbolic link
$ stat -L -c '%N %F' link.txt
'link.txt' regular file

ハードリンクのほうは様子が違い、inode 番号が同じままで Links の数だけが増えるという形で現れます。

$ stat -c '%i %h %n' note.txt hard.txt link.txt
21364 2 note.txt
21364 2 hard.txt
21365 1 link.txt

同じ実体を指す名前が2つある、というハードリンクの性質が、そのまま数字に出ているわけです。

リンクそのものの作り方と使い分けは別の記事にまとめているので、あわせてどうぞ。

シンボリックリンクとハードリンクの違い|lnの使い方

出力の Access: (0644/-rw-r–r–) の読み方が怪しいときは、パーミッションの記事から先に目を通すと早いはずです。

chmod 755と644の違いとrwxの読み方

最後に

stat は、ls -l では届かない一段深いところを覗くためのコマンドでした。

4つの時刻の意味と -c の書式さえ握っておけば、障害調査でも運用スクリプトでも十分に戦えます。

まずは手元のファイルに stat を1回打ってみるところから、どうぞ。

調べたい対象がシンボリックリンク越しなら、先に絶対パスへ直しておくと迷いません。

realpath・readlink入門|絶対パスに直す基本

以上です。

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

CAPTCHA