Linux 文件时间戳解释:atime、mtime 和 ctime

理解 Linux 文件时间戳:修改与改变的区别

在 Linux 系统中,时间戳不仅仅是简单的“修改”概念,它还涉及到“改变”的概念。本文将深入探讨 Linux 文件的时间戳机制,解释系统如何更新这些时间戳,以及用户如何手动修改它们。

访问时间、修改时间和更改时间:三者的区别

每个 Linux 文件都具有三个关键的时间戳:访问时间(atime)、修改时间(mtime)和更改时间(ctime)。

  • 访问时间 (atime):记录的是文件最后一次被读取的时间。例如,当程序读取文件的内容或从中提取数据时,会更新访问时间。此时,文件的数据本身并未发生任何更改。
  • 修改时间 (mtime):表示文件内容最后一次被修改的时间。当文件被编辑、数据被添加或删除时,会更新修改时间。
  • 更改时间 (ctime):并非指文件内容的修改,而是指文件元数据发生更改的时间。例如,文件权限的变更会更新更改时间。

值得一提的是,标准的 ext4 Linux 文件系统预留了文件创建时间戳的空间,但这功能尚未完全实现。虽然有时此时间戳会被填充,但其值的可靠性无法保证。

时间戳的内部结构

Linux 时间戳并非以日期和时间的形式存储,而是以数字形式表示,这个数字代表自 Unix纪元(1970 年 1 月 1 日午夜 00:00:00 UTC)以来经过的秒数。 Linux 时间戳忽略闰秒,因此它与实际时间会有细微差异。

当 Linux 需要显示时间戳时,它会将存储的秒数转换为可读的日期和时间。这一转换过程会考虑到计算机所在的位置和时区,确保月份显示使用正确的语言。然而,一个时间戳可以存储的秒数是有限的,大约为 2,147,483,647 秒。这意味着,如果将此秒数加到 Unix 纪元,并转换为日期,会得到 2038 年 1 月 19 日。因此,我们需要寻找替代的时间戳方案。

如何查看时间戳

可以使用 `ls` 命令查看文件的时间戳:

  • 查看修改时间 (mtime):使用 `ls -l dp.c`
  • 查看访问时间 (atime):使用 `ls -lu dp.c`
  • 查看更改时间 (ctime):使用 `ls -lc dp.c`

要同时查看所有时间戳,可以使用 `stat` 命令:

stat dp.c

时间戳显示中包含时区信息,例如 -0500 或 -0400,代表时区偏移量。文件系统以 UTC 记录时间戳,并在显示时转换为本地时区。这些偏移量并非直接存储,而是基于 UTC 时间戳、本地时区和夏令时情况动态计算得出的。

您可能还会看到一个“出生”时间戳,但此功能尚未实现,因此通常显示为连字符“-”。

修改时间戳

可以使用 `touch` 命令来修改文件的访问时间和修改时间:

  • 修改访问时间 (atime): `touch -a dp.c`, 将访问时间设置为当前时间
  • stat dp.c

  • 修改修改时间 (mtime):`touch -m dp.c`,将修改时间设置为当前时间
  • stat dp.c

  • 同时修改访问时间和修改时间:使用 `-d` 选项,并指定日期和时间,例如 `touch -d “2020-01-15 10:30:45” dp.c`
  • stat dp.c

  • 将一个文件的时间戳设置为另一个文件的时间戳:使用 `-r` 选项,例如 `touch dp.c -r dice_words.sl3`
  • stat dp.c

要仅更改文件的更改时间,可以修改文件的元数据,例如使用 `chmod +x dp` 命令,赋予文件执行权限。

stat dp

文件系统如何更新时间戳

文件系统在挂载时,可以通过选项来控制如何处理时间戳。这些选项通常在 `/etc/fstab` 文件中定义,该文件在系统启动时被读取。以下是一些常用的选项:

  • strictatime:每次访问文件时都更新访问时间戳,开销较大。
  • noatime:完全禁止更新文件和目录的访问时间戳。
  • nodiratime:允许更新文件的访问时间戳,但禁止更新目录的访问时间戳。
  • relatime:仅当访问时间超过 24 小时,或早于修改/更改时间时,才更新访问时间戳。这是最常用的方式,在性能和准确性之间取得了平衡。

可以通过查看 `/etc/fstab` 文件来了解当前系统设置的选项:

less /etc/fstab

# /etc/fstab: static file system information.
#
# Use 'blkid' to print the universally unique identifier for a
# device; this may be used with UUID= as a more robust way to name devices
# that works even if disks are added and removed. See fstab(5).
#
#                
# / was on /dev/sda1 during installation
UUID=4a143d08-8695-475b-8243-b13b56050fc2 / ext4 errors=remount-ro 0 1
/swapfile none swap sw 0 0
  

通常情况下,没有明确指定访问时间戳的选项时,系统会使用 `relatime` 方案。我们可以通过查看 `/proc/mounts` 文件并使用 `grep` 命令来确定当前系统所使用的选项,例如:

cat /proc/mounts | grep "sda"

结果会显示 `rw` (读写) 和 `relatime` 选项。

总之,`relatime` 方案会在以下情况下被使用:

  • 使用默认的 `/etc/fstab` 选项。
  • 使用 `relatime` `/etc/fstab` 选项。
  • `/etc/fstab` 中未指定访问时间戳选项,并且 Linux 内核版本为 2.6.30 或更高。

在我们的例子中,`/etc/fstab` 文件没有指定任何访问时间戳更新选项,所以 Linux 默认选择了 `relatime`。

时间戳的重要性

时间戳不仅提供了查看文件访问、修改和更改时间的简单方式,还为备份和同步软件提供了一种确定哪些文件需要备份的关键依据。了解如何操控时间戳可以帮助我们更有效地管理文件和执行备份操作。