UNIX/Linuxの部屋 用語集:タイムスタンプ

TOP UNIX/Linuxの部屋 UNIX/Linuxコマンド一覧 用語集 新版 由来/読み方辞書 環境変数マニュアル Cシェル変数 システム設定ファイル システムコール・ライブラリ ネットワークプログラミングの基礎知識 クラウドサービス徹底比較・徹底解説




用語集 タイムスタンプ UNIX におけるファイルの時刻管理 (atime/ctime/mtime) (更新時刻・更新日時・変更日時) このエントリーをはてなブックマークに追加

最終更新


UNIX・Linux のファイルには、一般的に 3つのタイムスタンプがある。
  • atime … 最終アクセス時刻 (access time)
  • mtime … 最終変更時刻 (modify time)
  • ctime … 最終ステータス変更時刻 (change time)



タイムスタンプの表示
ls -l で mtime、ls -lc で ctime、ls -lu で atime を表示することができる。
% ls -l abc.txt
-rw-r--r-- 1 user group 2052 Jan 8 16:55 abc.txt
⇒ mtime
% ls -lc abc.txt
-rw-r--r-- 1 user group 2052 Jan 8 16:53 abc.txt
⇒ ctime
% ls -lu abc.txt
-rw-r--r-- 1 user group 2052 Feb 12 08:31 abc.txt
⇒ atime
また、stat コマンドでもそれぞれのタイムスタンプを表示することができる。
% stat hoge.txt
File: `hoge.txt'
(略)
Access: 2018-05-10 21:14:12.372266973 +0900
Modify: 2018-05-10 21:14:11.165267108 +0900
Change: 2018-05-10 21:14:11.165267108 +0900

タイムスタンプの変更
atime・mtime は、touch コマンドを用いれば (つまり utimes(2) を用いれば) 任意の時刻を設定することが可能である。

しかし ctime に任意の時刻を設定することはできない。これは、chmod コマンドなどを使って ctime に現在時刻をセットすることはできるが、過去や未来の日時をセットできないということ。ただし fsdb コマンドなどで、ファイルシステムを直接いじれば何でもアリである。

atime・mtime・ctime の詳細
atime は、最後にファイルにアクセスした時刻のこと。より正確には、ファイル内容を read(2) した場合に変更される。ファイルをオープンしただけでは変更されないし、ファイル内容を write(2) しても変更されない。当然ながら、read(2) する権限がなかった場合も変更されない。

mtime は、最後にファイルを変更した時刻のこと。より正確には、ファイルに write(2) または truncate(2) した場合に変更される。

ctime は、最後にファイルを変更した時刻のこと。より正確には、ファイルに write(2) または truncate(2) した場合、そして inode データの修正を行った場合に変更される。inode データに含まれるのは、
  • ファイル名
  • ファイルサイズ
  • パーミッション
  • リンク数
  • オーナー・グループ
などである。つまり、write(2)・rename(2)・truncate(2)・chmod(2)・link(2)・chown(2) などのシステムコールを発行すると ctime が更新される。なお、たまに「ctime はファイル生成時刻 であり、Create TIME の略である」と解説している文章を見かけるが、誤り。

ファイル内容を write(2) や truncate(2) で更新した場合、mtime と ctime の両方が更新されることに注意 (ファイルサイズが変わらないように write(2) すれば、ctime は更新されないかと予想していたが、試してみると更新されてしまった)。

シンボリックリンクのタイムスタンプ
いまどきの UNIX ではシンボリックリンクそのものの atime, mtime, ctime を持っているが、シンボリックリンクそのもののタイムスタンプを変更できるのは lutimes(2) を持つ OS のみである。*BSD には lutimes(2) が実装されているのでシンボリックリンクそのものの atime・mtime を変更できるが、lutimes(2) を持たない Linux・Solaris・HP-UX では変更ができない。

ファイル生成時刻
伝統的な UNIX では、ファイル生成時刻は保持していない。ただし FreeBSD 5.x から使用されている UFS2 では、inode が生成された時刻「birthtime」という情報がある (struct stat の st_birthtime)。これぞまさしくファイル生成時刻と言えるだろう。NetBSD や macOS でも birthtime は使用可能である。

Linux 界隈では、ext4 よりファイル生成時刻 crtime が追加されているが、カーネルや glibc が未対応であるため、値を取り出すことができない状況が続いていた。2017年5月リリースの Linux-4.11 カーネルにて statx(2) システムコールが追加され、struct statx_timestamp stx_btime にて取得が可能になったので、早晩 glibc も対応が進むと思われる。

mount の noatime オプション
ファイルを read(2) すると atime が更新されてしまうが、更新には少なからず時間がかかる。たとえば web サーバなどの用途では、どのファイルが参照されたかは web サーバのログに記録すればよいので、atime を更新する価値がほとんどない。そのような場合、mount 時に noatime オプションを付加することで atime の更新が行われなくなり、少しだけパフォーマンスが向上する。
# mount -t ufs -o noatime /www

ファイルシステム
これまで「UNIX のファイルには、一般的に 3つのタイムスタンプがある」などと解説してきたが、実際にはファイルシステムにも依存する。

たとえば、UFS2 ではファイル生成時刻を保持できる。仮に Linux で UFS2 をマウントできたとして、Linux 側にファイル生成時刻を読み出すインタフェースがなかったとしたら、それを参照することはできない (Linux の UFS2 対応状況は知らない)。