很长一段时间以来,Linux 并没有关心文件创建日期,因为它常用的文件系统都不支持它们。然而现在,两种常用的文件系统(NTFS 和 ext4)都记录文件创建日期。
stat
然而,该命令仍然Birth: -
在 ext4 文件系统上输出,即使我们可以看到 ext4 已使用debugfs -R 'stat <inode_number>' /dev/file_device
.
当我研究这是为什么时,我看到其他人已经最近提交的关于它的错误报告,响应链接到上游问题它只是简单地指出“目前没有 Linux 内核接口来获取该信息 [文件创建日期]”。对我来说,这显然是值得注意的仍然stat
这种情况,因为人们多年来一直要求显示此信息(并且stat
确实输出一个Birth
字段,即使它显然还不支持它!他们是否在预期中添加了它?)
那么,目前是否仍然没有 Linux 内核接口来获取文件创建日期?是否有计划实现这一点?
答案1
编辑:好消息,statx()
已合并,因此应该在版本 4.11 中可用。
- https://lwn.net/Articles/716302/
- https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/?id=a528d35e8bfcc521d7cb70aaf03e1bd296c8493f
xstat() 工作(目前为 statx())于 2016 年进行了修订。
这次的过程更加严格(减少自行车脱落,同意放弃有争议的属性,因为它们可以在以后添加)。不幸的是,仍然有人对确切的界面提出异议,而且我还没有看到任何更新的参考资料。
答案2
因为它常用的文件系统都不支持它们
据我所知(抱歉,有一堆链接、内存和谷歌,没有什么凝聚力足以在此列出作为参考),这从来不是因为下划线系统不支持创建时间属性,而是因为它们甚至都不能同意这是一个有用的功能。
看http://www.pathname.com/fhs/pub/fhs-2.3.html
POSIX 列出了三个时间戳。它们都不是创建时间。
如果我没记错的话,争论是这样的:
> Give me a use case where we can't already do that using what we already have.
< Some examples were submitted
> All of these are convoluted beyond usefulness.
> Ok, Ok, *maybe* a couple of these don't suck.
> Now how do you see handling file systems that don't track this?
< several ideas that were not the same.
< Basically everyone had a special case that would work, but not
< one that always works. Fight about fallbacks and other special handling.
> Ok, lets table that for now. What should we call this field
< At least 6 different answers emerged.
> So, you want to break POSIX standards,
> you can't really come up with a good reason why,
> you can't come up with a good fall back, and
> you can't even come up with a name.
> Sounds like it's specific to the file system to me, and that
> should be "extended data" accessible by tools and not as
> a core stat in the Kernel.
现在很多都是记忆和阅读一些旧的邮件列表。我也没有真正处于争论的中心。由于嵌入式 Linux 系统的胖驱动程序的一些临时工作,我被列入了邮件列表。我之所以提到这一点,是因为肯定有比我对我只关心的事情的记忆更权威的来源。
我确实记得最重要的是这样一个事实:没有人能提出一个好的用例,没有人能就如何处理其他 40 个不支持创建时间的常用文件系统的字段达成一致,甚至为该领域命名也引发了一场激烈的争论。
答案3
诞生时间是在几个 Linux 本机文件系统中,而不仅仅是 ext4。
从 Linux 内核 4.11 版本开始(2017 年 4 月),有一个新的statx()
系统调用来检索它。然而,相应的包装函数尚未添加到 GNU libc 中(截至 2018-06-26)。2019年编辑现在已在 2.28 中添加),并且 GNU stat
、ls
、等工具find
尚未更新以使用它(2019-08-22 编辑GNU stat
/Linux 系统上的 glibc 2.28 或更高版本从 coreutils 8.31 开始支持它;2021-01-04 编辑GNU自 coreutils 8.32 起ls
就有了--time=birth
)
你可以用类似的东西来做到这perl
一点:
perl -MPOSIX -e '
require "syscall.ph";
$buf = "\0" x 0x100; # enough space for a struct statx
for (@ARGV) {
# hardcode: AT_FDCWD == -100
# AT_SYMLINK_NOFOLLOW = 0x100 (lstat()-like)
# STATX_BTIME = 0x800 for the mask
# 80: offset of the btime in the struct
syscall(&SYS_statx, -100, $_, 0x100, 0x800, $buf) == 0
or die "$_: $!\n";
($t, $n) = unpack("x80QQ", $buf);
$n = sprintf("%09d", $n);
print strftime("%F %T.$n %z\n", localtime $t)
}' -- "$file"
如果你syscall.ph
没有SYS_statx
,你也可以对其进行硬编码。在 amd64 架构上是 332。或者尝试:
printf '#include <syscall.h>\n__NR_statx\n' | gcc -E -xc - | tail -n 1
现在,出生时间已经很少有用了。这不是文件中数据的年龄(数据被写入文件后它们已被创建),也不一定是该文件在目录中以该名称出现的时间(它可能已创建为不同的名称并重命名或链接到那里,并且其内容或属性在其间多次更改)。
1 作为一种特殊情况,对于 ext4,如果创建的文件系统的 inode 大小为 128 字节,则不包括出生时间字段。