首发于 酷python

准确获取linux文件的创建时间

1. windows 与 linux 的文件创建时间

在windows系统上,一个文件有3个时间属性,他们分别是

  1. 创建时间
  2. 修改时间
  3. 访问时间

linux上的文件也有三个时间属性,分别是

  1. 访问时间(access time 简写为 atime)
  2. 修改时间(modify time 简写为mtime)
  3. 状态修改时间(change time 简写为ctime)

很多人误将linux系统上文件的ctime 对标成windows系统上的创建时间,这是不对的,ctime里的字母c是change的缩写而非create的缩写。当文件的元数据发生变化时,ctime就会发生改变,比如文件的权限,拥有者,所属的组,硬链接,当然也包括文件内容发生变化。

So,在linux系统上,无法获得文件的创建时间了么?这是一个复杂的问题,关于linux系统上为什么不记录文件的创建时间,有很多的讨论,有人认为文件的创建时间对于大多数人来说是无用的,可以用其他来代替:

  • 如果文件没有修改过,就等于mtime,即最后一次write时间
  • 如果文件没有被修改权限过,就等于ctime,即最后一次使用chmod的时间
  • 如果文件没有被读取过,就等于atime,即最后一个read的时间

这些理由我个人认为有些牵强,但现实的情况是,尽管linux没有提供创建时间,也没有影响大家使用,至少没有因为缺少创建时间导致谁的应用不可用,人们在程序设计上避开了文件的创建时间。

Linus 本人也对这个问题进行了深入的研究,windows系统虽然提供了文件的创建时间,但是允许修改,Linus认为这是 Unix ctime概念的一种变体 ,因此建议修改ctime语义以适应windows情况,毕竟,很少有人使用ctime。

但这种想法并未获得太多支持, 杰里米·艾里森(Jeremy Allison) 认为这将导致更可怕的混乱,宁愿意看到新增的表示创建时间的字段。

关于linux系统的文件创建时间的讨论,可以参考这篇文章 File creation times

2. Ext4 的crtime

一个令人惊喜的事实,如果文件系统的格式是ext4, 那么会保存文件的创建时间,在shell里输入 df -T ,得到类似如下的结果

[root@pyhost ~]# df -T
Filesystem     Type     1K-blocks    Used Available Use% Mounted on
/dev/vda1      ext4      41151808 3078828  35959548   8% /
devtmpfs       devtmpfs    497108       0    497108   0% /dev
tmpfs          tmpfs       507704       0    507704   0% /dev/shm
tmpfs          tmpfs       507704     536    507168   1% /run
tmpfs          tmpfs       507704       0    507704   0% /sys/fs/cgroup
tmpfs          tmpfs       101544       0    101544   0% /run/user/0

想要得到文件的创建时间,只需要两个步骤

步骤1, 获得文件的inode

[root@pyhost ~]# ls -i 1.txt 
269710 1.txt

步骤2, 使用debugfs

[root@pyhost ~]# debugfs -R 'stat <269710>' /dev/vda1
debugfs 1.42.9 (28-Dec-2013)
Inode: 269710   Type: regular    Mode:  0777   Flags: 0x80000
Generation: 1404159711    Version: 0x00000000:00000001
User:     0   Group:     0   Size: 6
File ACL: 0    Directory ACL: 0
Links: 1   Blockcount: 8
Fragment:  Address: 0    Number: 0    Size: 0
 ctime: 0x5eec2951:296cbae4 -- Fri Jun 19 10:56:17 2020
 atime: 0x5eec2953:6ca8a4dc -- Fri Jun 19 10:56:19 2020
 mtime: 0x5eec2951:27fe84e4 -- Fri Jun 19 10:56:17 2020
crtime: 0x5eeb81e8:6361f8bc -- Thu Jun 18 23:02:00 2020