如何找到文件的创建日期?


104

我想找出特定文件的创建日期,而不是修改日期或访问日期。

我已经尝试过ls -ltrhstat filename


5
Linux不跟踪创建时间,因为POSIX不需要。但是,Mac OS X使用HFS文件系统-在中的“出生时间”下查找stat(1)
200_success

2
Fedora 19 ext4文件系统确实设置了文件创建时间。我敢肯定还有更多的例子。请参阅下面stap用于检索创建时间的答案。
rickhg12hs 13-10-15

Answers:


88

POSIX标准仅定义了每个文件要存储的三个不同的时间戳:上次数据访问的时间,上次数据修改的时间以及文件状态上次更改的时间。

就是说,诸如ext4,Btrfs和JFS之类的现代Linux文件系统确实存储了文件创建时间(也就是出生时间),但是为所涉及的字段(crtime在ext4中,otime在Btrfs和JFS中)使用了不同的名称。但是,当前Linux甚至在支持它们的文件系统上都没有提供用于访问文件创建时间的内核API

正如Craig SandersMohsen Pahlevanzadeh所指出的那样,stat确实支持%w%W格式说明符来显示文件的诞生时间(分别以人类可读的格式和距Epoch的秒数)。但是,stat它本身get_stat_birthtime()通过gnulib(in lib/stat-time.h)提供的访问出生时间,该时间从系统调用返回的结构的st_birthtimest_birthtimensec字段中获取出生时间。例如,BSD系统(和扩展OS X)通过提供,而Linux没有。这就是为什么即使在确实在内部存储创建时间的文件系统上,在Linux上输出(表示未知的创建时间)的原因。statstat()st_birthtimestatstat -c '%w' file-

正如Stephane Chazelas指出的那样,某些文件系统(例如ntfs-3g)通过扩展的文件属性公开文件创建时间。


4
在Linux上,它现在存储在包括ext4在内的许多文件系统中。虽然还没有内核API。像NTFS-3G在保险丝一些文件系统使其可以通过扩展属性API
斯特凡Chazelas

@StephaneChazelas谢谢您的评论。更新了答案以提供更多详细信息。
Thomas Nyman 2013年

您可以stap用来创建自己的内核API。参见答案示例。
rickhg12hs 13-10-15

26

TLDR;使用stap“ SystemTap”)创建自己的内核API。ext4创建时间提取的演示如下。

您可以在Fedora 19系统上提取ext4的创建时间。这是我的:

$ uname -a
Linux steelers.net 3.11.1-200.fc19.i686.PAE #1 SMP Sat Sep 14 15:20:42 UTC 2013 i686 i686 i386 GNU/Linux

显然,我的ext4分区上的inode具有创建时间。这是一个Shell脚本,该脚本确定与文件名关联的索引节点,然后stat使用stap(“ systemtap”)增加创建时间的输出。

注意:这只是一个演示和巨大低效的,因为内核模块中创建,加载和卸载的每个执行。由于未执行错误检查,因此这也可能非常脆弱。适当的内核API是更可取的,但是可以使此脚本更有效,并读取多个文件/节点的创建时间。

[stap_stat.sh的内容]

#/bin/sh

my_inode_str=$(stat --printf="%i" $1)

stap - << end_of_stap_script
global my_offsetof
probe begin {
  system("stat $1");
  my_offsetof = &@cast(0,"struct ext4_inode_info")->vfs_inode;
}
probe kernel.function("ext4_getattr@fs/ext4/inode.c") {
  probe_inode=\$dentry->d_inode;
  if (@cast(probe_inode, "struct inode")->i_ino == $my_inode_str) {
    my_i_crtime = &@cast(probe_inode - my_offsetof,"struct ext4_inode_info")->i_crtime;
    printf("CrTime: %s GMT\n", ctime(@cast(my_i_crtime, "timespec")->tv_sec));
    printf("CrTime (nsecs): %d\n", @cast(my_i_crtime, "timespec")->tv_nsec);
    exit();
  }
}
end_of_stap_script

这是一个演示:

$ ll testfile
ls: cannot access testfile: No such file or directory
$ touch testfile
$ ./stap_stat.sh testfile
  File: ‘testfile’
  Size: 0           Blocks: 0          IO Block: 4096   regular empty file
Device: fd02h/64770d    Inode: 4850501     Links: 1
Access: (0664/-rw-rw-r--)  Uid: ( 1001/    Rick)   Gid: ( 1001/    Rick)
Context: unconfined_u:object_r:user_home_t:s0
Access: 2013-09-28 06:17:04.221441084 -0400
Modify: 2013-09-28 06:17:04.221441084 -0400
Change: 2013-09-28 06:17:04.221441084 -0400
 Birth: -
CrTime: Sat Sep 28 10:17:04 2013 GMT
CrTime (nsecs): 220441085
$ ll testfile
-rw-rw-r--. 1 Rick Rick 0 Sep 28 06:17 testfile
$ cat - >> testfile 
Now is the time ...
$ ll testfile 
-rw-rw-r--. 1 Rick Rick 20 Sep 28 06:18 testfile
$ ./stap_stat.sh testfile
  File: ‘testfile’
Device: fd02h/64770d    Inode: 4850501     Links: 1
Access: (0664/-rw-rw-r--)  Uid: ( 1001/    Rick)   Gid: ( 1001/    Rick)
Context: unconfined_u:object_r:user_home_t:s0
Access: 2013-09-28 06:17:04.221441084 -0400
Modify: 2013-09-28 06:18:33.684374740 -0400
Change: 2013-09-28 06:18:33.684374740 -0400
 Birth: -
CrTime: Sat Sep 28 10:17:04 2013 GMT
CrTime (nsecs): 220441085
$ cat testfile 
Now is the time ...
$ ./stap_stat.sh testfile
  File: ‘testfile’
  Size: 20          Blocks: 8          IO Block: 4096   regular file
Device: fd02h/64770d    Inode: 4850501     Links: 1
Access: (0664/-rw-rw-r--)  Uid: ( 1001/    Rick)   Gid: ( 1001/    Rick)
Context: unconfined_u:object_r:user_home_t:s0
Access: 2013-09-28 06:19:12.199349463 -0400
Modify: 2013-09-28 06:18:33.684374740 -0400
Change: 2013-09-28 06:18:33.684374740 -0400
 Birth: -
CrTime: Sat Sep 28 10:17:04 2013 GMT
CrTime (nsecs): 220441085
$ mv testfile testfile2
$ ./stap_stat.sh testfile2 
  File: ‘testfile2’
  Size: 20          Blocks: 8          IO Block: 4096   regular file
Device: fd02h/64770d    Inode: 4850501     Links: 1
Access: (0664/-rw-rw-r--)  Uid: ( 1001/    Rick)   Gid: ( 1001/    Rick)
Context: unconfined_u:object_r:user_home_t:s0
Access: 2013-09-28 06:19:12.199349463 -0400
Modify: 2013-09-28 06:18:33.684374740 -0400
Change: 2013-09-28 06:20:45.870295668 -0400
 Birth: -
CrTime: Sat Sep 28 10:17:04 2013 GMT
CrTime (nsecs): 220441085
$ 

4
好的,这很酷。+1使用stap,猴子修补Linux内核,真棒。
克里斯·马格努森

@ChrisMagnuson:无需猴子修补内核debugfs + stat即可获取crtime
jfs

17

ext4可能的情况下;因为ext4文件系统会存储文件创建时间。但是,您仍然会发现该stat命令无法显示日期,因为我认为内核对此没有任何API。

无论如何,文件的出生时间都存储在其中ext4,您可以找到它,虽然不是通过直接方法,而是通过使用debugfs

sudo debugfs -R“ stat / ABSOLUTE / PATH” / dev / sdxX | grep crtime


1
作为bash函数:xstat filename
jfs

1
如果/dev/sdxX安装在/some/path且文件为/some/path/some/file,则仅指定some/file路径:该路径必须不指向文件系统根目录,而必须指向安装点。否则,将找不到该文件。
BowPark '18

15

从理论上讲,通过GNU stat,您可以使用stat -c '%w'%W获取文件的创建日期(也称为出生时间)。

实际上,大多数文件系统都不记录该信息,并且Linux内核不提供任何访问信息的方式。

您可以获取的最接近的是文件的ctime,而不是创建时间,它是文件元数据最后一次更改的时间。

《 Linux周刊新闻》几年前有一篇有趣的文章-http://lwn.net/Articles/397442/


7
stat --printf='%w' yourfile   #human readable

stat --printf='%W' yourfile   #seconds from Epoch , 0 if unknown

区别FreeBSDGNU\Linuxstat command

如果您statGNU\Linux其中调用command 会调用该-x 选项,但是在FreeBSD中,您应该自己调用该-x选项。

另请参见Linux上的哪些文件系统会存储创建时间?

注意: --printfscripting..!中非常有用。


//,在CEntOS 6机器上进行了尝试,我得到的只是问号:$ stat --printf ='%w'〜/ dump.rdb?也许我的文件系统不支持%w的统计信息。
弥敦道(Nathan Basanese),2015年

不幸的是,HFS不支持ctime。
PersianGulf 2015年

5

在OS X,你可以使用ls -lUstat -f%BGetFileInfo -d,或mdls -n kMDItemFSCreationDate

$ ls -lU
total 0
-rw-r--r--  1 lauri  staff  0 Apr 25 03:58 a
$ stat -f%B a
1398387538
$ stat -f%SB -t %Y%m%d%H%M a
201404250358
$ GetFileInfo -d a
04/25/2014 03:58:58
$ mdls -n kMDItemFSCreationDate a
kMDItemFSCreationDate = 2014-04-25 00:58:58 +0000

2

看一下这个:

# the last arg is the device to scan in.
debugfs -R 'stat /home/renich/somefile' /dev/sda1

顺便说一句,这仅适用于ext4。我还没有找到BtrFS的解决方案...;)


1
那几乎就是初学者的回答……不是吗?
don_crissti 2015年

糟糕,您说得对@don_crissti
Renich
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.