我想找出 Linux 系统上特定文件的创建日期。不是修改日期或访问日期,而是创建日期。
我尝试过ls -ltrh
和 ,stat filename
但都没有给我我需要的东西。我还能做什么来获取这些信息?
答案1
stat -c '%w' file
在存储创建时间的文件系统上。
请注意,在 Linux 上这需要coreutils
8.31、2.28glibc
和内核版本 4.11 或更高版本。
POSIX 标准仅定义三个不同的时间戳为每个文件存储:最后一次数据访问的时间、最后一次数据修改的时间、最后一次文件状态改变的时间。
现代 Linux 文件系统,例如 ext4、Btrfs、XFS(v5 及更高版本)和 JFS,存储文件创建时间(又名出生时间),但对相关字段使用不同的名称(crtime
在 ext4/XFS 中、otime
在 Btrfs 和 JFS 中)。 Linux 提供了统计数据(2)系统调用接口,用于检索自内核版本 4.11 以来支持它的文件系统的文件出生时间。 (因此,即使在文件系统中添加了创建时支持,一些已部署的内核也不会立即支持它,即使在为该文件系统版本添加了名义支持之后,例如,XFS v5.)
作为克雷格·桑德斯和莫森·帕勒万扎德指出,在8.31 版本之前,stat
确实支持%w
和%W
格式说明符来显示文件生成时间(分别以人类可读的格式和自纪元以来的秒数) 。coreutils
但是,仅自版本 8.31 起才coreutils
stat
使用statx()
可用的系统调用来检索出生时间。在coreutils
版本 8.31之前,通过gnulib 提供的(在)stat
中访问出生时间,它从系统调用返回的结构体的和字段中获取出生时间。例如,BSD 系统(以及 OS X 的扩展)提供via ,而 Linux 则不提供。这就是为什么在 8.31之前的 Linux 上会输出(指示未知的创建时间) ,即使对于内部存储创建时间的文件系统也是如此。get_stat_birthtime()
lib/stat-time.h
st_birthtime
st_birthtimensec
stat
stat()
st_birthtime
stat
stat -c '%w' file
-
coreutils
作为斯蒂芬·查泽拉斯指出,某些文件系统(例如 ntfs-3g)通过扩展文件属性公开文件创建时间。
答案2
太长了;使用stap
(“系统点击”) 创建您自己的内核 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 分区上的索引节点有创建时间。下面是一个 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
$
答案3
理论上,使用 GNU stat 您可以使用stat -c '%w'
或%W
来获取文件的创建日期(也称为出生时间)。
实际上,大多数文件系统不记录该信息,并且 Linux 内核不提供任何访问它的方法。
您可以获得的最接近的是文件的 ctime,即不是创建时间,即文件元数据最后一次更改的时间。
Linux Weekly News 几年前有一篇关于此的有趣文章 -文件创建时间。
答案4
在 OS X 中,您可以使用ls -lU
、stat -f%B
、GetFileInfo -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