ext4 上的出生是空的

xen*_*ide 100 filesystems ext4 stat

我刚刚阅读了 的Birth部分,stat似乎 ext4 应该支持它,但即使是我刚刚创建的文件也将其留空。

 ~  % touch test                                                       slave-iv
 ~  % stat test.pl                                                     slave-iv
  File: ‘test.pl’
  Size: 173             Blocks: 8          IO Block: 4096   regular file
Device: 903h/2307d      Inode: 41943086    Links: 1
Access: (0600/-rw-------)  Uid: ( 1000/xenoterracide)   Gid: (  100/   users)
Access: 2012-09-22 18:22:16.924634497 -0500
Modify: 2012-09-22 18:22:16.924634497 -0500
Change: 2012-09-22 18:22:16.947967935 -0500
 Birth: -

 ~  % sudo tune2fs -l /dev/md3 | psp4                                  slave-iv
tune2fs 1.42.5 (29-Jul-2012)
Filesystem volume name:   home
Last mounted on:          /home
Filesystem UUID:          ab2e39fb-acdd-416a-9e10-b501498056de
Filesystem magic number:  0xEF53
Filesystem revision #:    1 (dynamic)
Filesystem features:      has_journal ext_attr resize_inode dir_index filetype needs_recovery extent flex_bg sparse_super large_file huge_file uninit_bg dir_nlink extra_isize
Filesystem flags:         signed_directory_hash 
Default mount options:    journal_data
Filesystem state:         clean
Errors behavior:          Continue
Filesystem OS type:       Linux
Inode count:              59736064
Block count:              238920960
Reserved block count:     11946048
Free blocks:              34486248
Free inodes:              59610013
First block:              0
Block size:               4096
Fragment size:            4096
Reserved GDT blocks:      967
Blocks per group:         32768
Fragments per group:      32768
Inodes per group:         8192
Inode blocks per group:   512
RAID stride:              128
RAID stripe width:        256
Flex block group size:    16
Filesystem created:       Mon May 31 20:36:30 2010
Last mount time:          Sat Oct  6 11:01:01 2012
Last write time:          Sat Oct  6 11:01:01 2012
Mount count:              14
Maximum mount count:      34
Last checked:             Tue Jul 10 08:26:37 2012
Check interval:           15552000 (6 months)
Next check after:         Sun Jan  6 07:26:37 2013
Lifetime writes:          7255 GB
Reserved blocks uid:      0 (user root)
Reserved blocks gid:      0 (group root)
First inode:              11
Inode size:           256
Required extra isize:     28
Desired extra isize:      28
Journal inode:            8
First orphan inode:       55313243
Default directory hash:   half_md4
Directory Hash Seed:      442c66e8-8b67-4a8c-92a6-2e2d0c220044
Journal backup:           inode blocks
Run Code Online (Sandbox Code Playgroud)

为什么我的ext4分区没有填充这个字段?

don*_*sti 116

该字段被填充(见下文)仅coreutils stat不显示它。显然,他们正在等待1xstat()接口

coreutils 补丁 - 八月。2012 - 待办事项

stat(1) 和 ls(1) 支持出生时间。依赖于内核提供的 xstat()

您可以通过debugfs以下方式获取创建时间:

debugfs -R 'stat <inode_number>' DEVICE
Run Code Online (Sandbox Code Playgroud)

例如,对于我/etc/profile打开的/dev/sda2(请参阅如何找出文件所在的设备):

stat -c %i /etc/profile
398264
stat -c %i /etc/profile
398264

时间字段含义:

  • ctime: 文件更改时间。
  • atime: 文件访问时间。
  • mtime: 文件修改时间。
  • crtime: 文件创建时间。

1 Linus 在 LKML线程上的回复

  • @Sparhawk:我对文件`/home/user/path/to/file` 也有这个问题,因为`/home` 在一个单独的分区上。在这种情况下,提供给 `stat` 的路径必须相对于 `/home`。示例:`sudo debugfs -R 'stat user/path/to/file' /dev/sda2`。为了摆脱路径处理,我们可以向 `stat` 提供 inode 编号而不是路径:`sudo debugfs -R "stat &lt;$(stat -c %i /home/user/path/to/file)&gt; " /dev/sda5` (9认同)
  • 请注意,inode 编号周围的 `&lt;` 和 `&gt;` 是必需的。它们通常在示例中用于包围应调整的变量,但在这种情况下,它们必须按字面意思输入。如果没有它们,inode 编号将被视为路径,并且您会收到“文件未找到 ext2_lookup”错误。 (4认同)
  • 这可以用于从网络安装的文件系统中获取文件的创建时间吗? (3认同)
  • @sinekonata 文件元数据非常依赖于系统(正如这个答案所示,操作系统的每一层都必须能够处理它)并且在机器之间的副本中保存它依赖于系统*和*复制工具对该元数据格式的支持. 这意味着:如果您甚至获得未损坏的文件名,您就很幸运了。或者,某些文件格式允许您在文件*内部*插入元数据(例如 [ID3](https://en.wikipedia.org/wiki/ID3)),这通常很好,但许多格式没有这样的功能。最后,您可以将文件放入存档文件中,例如 (2认同)

ter*_*don 42

我把它组合成一个简单的 shell 函数:

get_crtime() {
  for target in "${@}"; do
    inode=$(stat -c %i "${target}")
    fs=$(df  --output=source "${target}"  | tail -1)
    crtime=$(sudo debugfs -R 'stat <'"${inode}"'>' "${fs}" 2>/dev/null | 
    grep -oP 'crtime.*--\s*\K.*')
    printf "%s\t%s\n" "${target}" "${crtime}"
  done
    }
Run Code Online (Sandbox Code Playgroud)

然后你可以运行它

$ get_crtime foo foo/file /etc/
foo Wed May 21 17:11:08 2014
foo/file    Wed May 21 17:11:27 2014
/etc/   Wed Aug  1 20:42:03 2012
Run Code Online (Sandbox Code Playgroud)


mur*_*uru 28

xstat功能从未合并到主线中。然而,statx后来提出了一个新的调用,并在 Linux 4.11合并。新的statx(2)系统调用在其返回结构中包含创建时间。statx(2)仅在2.28(2018 年 8 月发布)中向 glibc 添加了一个包装器。GNU coreutils 8.31(2019 年 3 月发布)中添加了对使用此包装器的支持:

stat 现在在文件系统支持时打印文件创建时间,在 glibc >= 2.28 和内核 >= 4.11 的 GNU Linux 系统上。

% stat --version
stat (GNU coreutils) 8.31
Copyright (C) 2019 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <https://gnu.org/licenses/gpl.html>.
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

Written by Michael Meskes.
% stat /
  File: /
  Size: 4096            Blocks: 8          IO Block: 4096   directory
Device: b302h/45826d    Inode: 2           Links: 17
Access: (0755/drwxr-xr-x)  Uid: (    0/    root)   Gid: (    0/    root)
Access: 2019-06-06 20:03:12.898725626 +0900
Modify: 2019-05-28 05:15:44.452651395 +0900
Change: 2019-05-28 05:15:44.452651395 +0900
 Birth: 2018-06-07 20:35:54.000000000 +0900
Run Code Online (Sandbox Code Playgroud)

接下来是statx用户空间尚未赶上的演示(较旧的 glibc 或 coreutils)。在 C 程序中直接调用系统调用并不容易。通常,glibc 提供了一个使工作变得简单的包装器,但幸运的是,@whotwagner 编写了一个示例 C 程序,展示了如何statx(2)在 x86 和 x86-64 系统上使用系统调用。它的输出与stat的默认格式相同,没有任何格式选项,但修改它以仅打印出生时间很简单。(如果您有足够新的 glibc,则不需要它 - 您可以statx按照 中所述直接使用man 2 statx)。

首先,克隆它:

git clone https://github.com/whotwagner/statx-fun
Run Code Online (Sandbox Code Playgroud)

您可以编译statx.c代码,或者,如果您只想要出生时间,请birth.c使用以下代码在克隆目录中创建一个(这是statx.c仅打印包含纳秒精度的创建时间戳的最小版本):

% stat --version
stat (GNU coreutils) 8.31
Copyright (C) 2019 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <https://gnu.org/licenses/gpl.html>.
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

Written by Michael Meskes.
% stat /
  File: /
  Size: 4096            Blocks: 8          IO Block: 4096   directory
Device: b302h/45826d    Inode: 2           Links: 17
Access: (0755/drwxr-xr-x)  Uid: (    0/    root)   Gid: (    0/    root)
Access: 2019-06-06 20:03:12.898725626 +0900
Modify: 2019-05-28 05:15:44.452651395 +0900
Change: 2019-05-28 05:15:44.452651395 +0900
 Birth: 2018-06-07 20:35:54.000000000 +0900
Run Code Online (Sandbox Code Playgroud)

然后:

$ make birth
$ ./birth ./birth.c
1511793291.254337149
$ ./birth ./birth.c | xargs -I {} date -d @{}
Mon Nov 27 14:34:51 UTC 2017
Run Code Online (Sandbox Code Playgroud)

从理论上讲,这应该使创建时间可以在更多文件系统上访问,而不仅仅是 ext* 文件系统(debugfs是用于 ext2/3/4 文件系统的工具,在其他文件系统上不可用)。它确实适用于 XFS 系统,但不适用于 NTFS 和 exfat。我猜那些的 FUSE 文件系统不包括创建时间。


Kev*_* Li 7

从 GNU coreutils 的 8.31 版开始,stat“现在在文件系统支持时,在 glibc >= 2.28 和内核 >= 4.11 的 GNU Linux 系统上打印文件创建时间。”

我的操作系统(Ubuntu 20.04,它带有 Linux 内核 5.4.0-28 和 GLIBC 2.31)只带有 GNU coreutils 8.30,所以我必须通过从 source 编译 GNU coreutils 的 8.32 版来验证。

的输出ls -l --time=birth --time-style=full-iso --no-group

$ ls -l --time=birth --time-style=full-iso --no-group
total 13477610
-rwxr--r-- 1 systemd-coredump 13801071714 2017-06-30 04:53:33.211517792 -0400  file
Run Code Online (Sandbox Code Playgroud)

statbtrfs 文件系统上的输出:

$ stat file
  File: /mnt/btrfs/file
  Size: 13801071714 Blocks: 26955224   IO Block: 4096   regular file
Device: 33h/51d Inode: 4998        Links: 1
Access: (0744/-rwxr--r--)  Uid: (  999/systemd-coredump)   Gid: (  999/systemd-coredump)
Access: 2020-05-04 12:21:51.640487614 -0400
Modify: 2016-01-19 10:32:19.272000000 -0500
Change: 2017-06-30 04:55:14.910839537 -0400
 Birth: 2017-06-30 04:53:33.211517792 -0400
Run Code Online (Sandbox Code Playgroud)

(奇怪的是,我无法使用虚拟 ext4 文件系统在 Arch Linux 上显示任何出生时间,尽管它满足了上述所有要求。)


旧答案:

那么,作为GNU的coreutils 8.32版(稳定版),都statls使用statx电话。

ls 将显示创建/出生时间。

** 新功能

ls 现在支持 --time=birth 选项以
在可用的情况下按文件创建时间显示和排序。

据推测,stat也会。

** 改进

stat 和 ls 现在在可用的情况下使用 statx() 系统调用,它可以通过仅检索请求的属性来更有效地运行。

它是全新的,刚刚于 2020 年 3 月 5 日发布,因此除非您使用像 Arch Linux 这样的前沿发行版,否则可能需要一段时间才能真正应用。(Arch Linux于 2020 年 4 月 1 日获得了coreutils包的8.32-1 版)。

  • 请不要发布文字截图。https://unix.meta.stackexchange.com/q/4086/70524 (2认同)

Fra*_*iat 6

还有另一种情况,出生时间将为空/零/破折号:Ext4 的 Inode 大小必须至少为 256 字节才能存储crtime. 如果您最初创建的文件系统小于 512MB(默认 Inode 大小为 128 字节,请参阅/etc/mke2fs.confmkfs.ext4联机帮助页),则会出现问题。

stat -c '%n: %w' testfile
testfile: -  
Run Code Online (Sandbox Code Playgroud)

和/或

stat -c '%n: %W' testfile
testfile: 0
Run Code Online (Sandbox Code Playgroud)

现在检查文件系统 inode(它是否足以存储crtime?):

tune2fs -l $(df . --output=source | grep ^/) | grep "Inode size:"
Inode size:           128
Run Code Online (Sandbox Code Playgroud)

技术信息:在Ext4 磁盘布局页面上,请注意 inode 表的某些属性超出 0x80 (128)。