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不显示它。显然,他们正在等待1的xstat()接口。
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线程上的回复
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 文件系统不包括创建时间。
从 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版(稳定版),都stat和ls使用statx电话。
ls 将显示创建/出生时间。
** 新功能
ls 现在支持 --time=birth 选项以
在可用的情况下按文件创建时间显示和排序。
据推测,stat也会。
** 改进
stat 和 ls 现在在可用的情况下使用 statx() 系统调用,它可以通过仅检索请求的属性来更有效地运行。
它是全新的,刚刚于 2020 年 3 月 5 日发布,因此除非您使用像 Arch Linux 这样的前沿发行版,否则可能需要一段时间才能真正应用。(Arch Linux于 2020 年 4 月 1 日获得了coreutils包的8.32-1 版)。
还有另一种情况,出生时间将为空/零/破折号:Ext4 的 Inode 大小必须至少为 256 字节才能存储crtime. 如果您最初创建的文件系统小于 512MB(默认 Inode 大小为 128 字节,请参阅/etc/mke2fs.conf和mkfs.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)。