在前面文章 Linux 链接文件详解中提到了 inode 信息。在 inode 的中包含三种文件时间戳:mtime、atime、ctime。
含义
| 简写 | 全称 | 描述 |
|---|---|---|
| mtime | Modify Time | 修改时间,表示文件内容最后一次修改的时间。 |
| atime | Access Time | 访问时间,表示文件最后一次访问(读取或执行)的时间。 |
| ctime | Change Time | 改变时间,表示文件最后一次改变(包括属性、权限、链接个数等)的时间。 |
获取文件时间
可以选择通过 stat 或 ls 命令获取文件时间。
$ stat -x README.md
File: "README.md"
Size: 21 FileType: Regular File
Mode: (0644/-rw-r--r--) Uid: ( 501/ frankie) Gid: ( 20/ staff)
Device: 1,5 Inode: 59499107 Links: 1
Access: Sun Jul 10 19:57:53 2022
Modify: Sun Jul 10 19:57:51 2022
Change: Sun Jul 10 19:57:51 2022
Birth: Sun Jul 10 19:57:26 2022
使用 ls 命令的话,有几个参数:
更多可看这里。
$ ls -l
total 56
-rw-r--r-- 1 frankie staff 21 7 10 19:57 README.md
-rw-r--r-- 1 frankie staff 13 7 10 20:29 a-symlink-absolute.txt
-rw-r--r-- 1 frankie staff 13 7 10 20:29 a-symlink-relative.txt
-rw-r--r-- 1 frankie staff 13 7 10 20:29 a-symlink.txt
-rw-r--r--@ 1 frankie staff 13 7 10 20:00 a.txt
-rw-r--r-- 1 frankie staff 960 7 10 20:29 a.txt的替身
-rw-r--r-- 1 frankie staff 92 7 10 19:57 package.json
drwxr-xr-x 2 frankie staff 64 7 10 19:57 src
相关命令操作对文件时间的影响
其中 ❌ 表示对应时间不发生改变,✅ 则表示对应时间发生了改变。
| 命令 | mtime | atime | ctime |
|---|---|---|---|
| cat | ❌ | ❌ | ❌ |
| cp | ❌ | ❌ | ❌ |
| mv | ❌ | ✅ | ✅ |
| chmod | ❌ | ❌ | ✅ |
| chown | ❌ | ❌ | ✅ |
| touch | ✅ | ✅ | ✅ |
| >、>> | ✅ | ✅ | ✅ |
| vim、vi(不修改时) | ❌ | ❌ | ✅ |
| vim、vi(修改时) | ✅ | ✅ | ✅ |
| 执行可执行文件 | ❌ | ✅ | ❌ |
关于 cat、cp 等命令不会更改 atime 的原因
从命令语义看,无论是读取文件内容,还是复制文件,肯定是访问源文件的,这样按理来讲就应该更新文件的 atime。在 Linux kernel 2.6 以前确实如此,但后来发现 OS 更新 atime 的开销很大,会造成频繁的写操作。
为了提高性能,虽然可以完全禁止 atime 的修改(详看 mount 命令的 noatime 和 nodiratime 选项),但这会破坏 POSIX 兼容性。比如某些备份软件需要通过对比 atime、mtime、ctime 的时间来判断是否需要进行备份。
针对这个问题,Linux kernel 2.6.20 开始为 mount 引入了 relatime 选项,并从 2.6.30 开始默认开启此选项。
当开启 relatime 选项后,只有当 atime < mtime 或 atime < ctime 时,才会去更新 atime。通过这种方式,既能大幅度减少 atime 引起的写操作,也保证了备份软件不受到影响。
此设计非常精妙,这也成了很多系统的默认设置。

