如何在 Bash/Debian 中获取文件创建日期/时间?

Posted

技术标签:

【中文标题】如何在 Bash/Debian 中获取文件创建日期/时间?【英文标题】:How to get file creation date/time in Bash/Debian? 【发布时间】:2013-01-28 07:53:22 【问题描述】:

我在 Debian GNU/Linux 6.0 上使用 Bash。是否可以获得文件创建日期/时间?不是修改日期/时间。 ls -lh a.txtstat -c %y a.txt 都只给出修改时间。

【问题讨论】:

您是否使用记录创建时间的文件系统?大多数人没有。 见askubuntu.com/questions/470134/… 【参考方案1】:

不幸的是,您的任务通常是不可能的,因为按照 POSIX 标准的定义,您的每个文件只存储了 3 个不同的时间值(请参阅Base Definitions section 4.8 File Times Update)

每个文件都有三个不同的关联时间戳:最后的时间 数据访问,最后一次数据修改时间,文件时间 状态上次更改。这些值在文件中返回 特征结构struct stat,如<sys/stat.h>中所述。

编辑:如下面的 cmets 所述,根据使用的文件系统,元数据可能包含文件创建日期。但是请注意,此类信息的存储是非标准的。取决于它可能会导致迁移到另一个文件系统的可移植性问题,以防实际使用的文件系统以某种方式存储它。

【讨论】:

这样的不幸消息。现在可以轻松确定文件是否已被删除并重新创建或一直存在,这将非常有用。 你知道它在 Mac 上是如何工作的吗? Finder 将三个时间戳显示为“已创建”、“已修改”、“上次打开结束”... 强烈依赖于使用的文件系统。但无论如何都是好点。 :) 尝试将缺少的信息添加到帖子中。 @mikyra ext4 存储创建日期。【参考方案2】:
ls -i file #output is for me 68551981
debugfs -R 'stat <68551981>' /dev/sda3 # /dev/sda3 is the disk on which the file exists

#results - crtime value
[root@loft9156 ~]# debugfs -R 'stat <68551981>' /dev/sda3
debugfs 1.41.12 (17-May-2010)
Inode: 68551981   Type: regular    Mode:  0644   Flags: 0x80000
Generation: 769802755    Version: 0x00000000:00000001
User:     0   Group:     0   Size: 38973440
File ACL: 0    Directory ACL: 0
Links: 1   Blockcount: 76128
Fragment:  Address: 0    Number: 0    Size: 0
 ctime: 0x526931d7:1697cce0 -- Thu Oct 24 16:42:31 2013
 atime: 0x52691f4d:7694eda4 -- Thu Oct 24 15:23:25 2013
 mtime: 0x526931d7:1697cce0 -- Thu Oct 24 16:42:31 2013
**crtime: 0x52691f4d:7694eda4 -- Thu Oct 24 15:23:25 2013**
Size of extra inode fields: 28
EXTENTS:
(0-511): 352633728-352634239, (512-1023): 352634368-352634879, (1024-2047): 288392192-288393215, (2048-4095): 355803136-355805183, (4096-6143): 357941248-357943295, (6144
-9514): 357961728-357965098

【讨论】:

ctime、atime、mtime是什么意思? @Velthune 创建时间、访问时间、修改时间。但是,根据文件系统的配置方式,这些值可能准确,也可能不准确。例如,许多人禁用写入文件的上次访问时间以节省额外的磁盘写入。 @indivisible:错误! POSIX 标准将 ctime 定义为更改时间。这通常是某些文件属性发生变化的时候。 我不知道标准,但是这里的ctime是在atime之后。我认为创建时间应该是最古老的...... 修改时间和修改时间有什么区别?【参考方案3】:

mikyra 的回答很好。事实和他说的一样。

[jason@rh5 test]$ stat test.txt
  File: `test.txt'
  Size: 0               Blocks: 8          IO Block: 4096   regular empty file
Device: 802h/2050d      Inode: 588720      Links: 1
Access: (0664/-rw-rw-r--)  Uid: (  500/   jason)   Gid: (  500/   jason)
Access: 2013-03-14 01:58:12.000000000 -0700
Modify: 2013-03-14 01:58:12.000000000 -0700
Change: 2013-03-14 01:58:12.000000000 -0700

如果您想验证最先创建的文件,您可以在创建一系列文件时通过附加系统日期来构建文件名。

【讨论】:

当我执行 stat myfile.txt 时,我得到另一行:出生。不幸的是,它没有任何价值。为什么会有那一行? 它是另一个文件系统的占位符,可以存储创建日期。【参考方案4】:

请注意,如果您出于性能原因使用 noatime 挂载文件系统,则 atime 可能会显示创建时间。鉴于 noatime 会带来巨大的性能提升(通过在每次读取文件时删除磁盘写入),它可能是一个合理的配置选项,也可以为您提供所需的结果。

【讨论】:

我不能保证性能提升,但我阅读了推荐 noatime 的 SSD 指南,所以这对我有用。【参考方案5】:

创建日期/时间通常存储。所以不,你不能。

【讨论】:

【参考方案6】:

ls -i menus.xml

94490 菜单.xml 这里的数字94490代表inode

然后做一个:

df -h

Filesystem            Size  Used Avail Use% Mounted on
/dev/mapper/vg-root   4.0G  3.4G  408M  90% /
tmpfs                 1.9G     0  1.9G   0% /dev/shm
/dev/sda1             124M   27M   92M  23% /boot
/dev/mapper/vg-var    7.9G  1.1G  6.5G  15% /var

要找到根“/”文件系统的挂载点,因为文件menus.xml在'/'即'/dev/mapper/vg-root'上

debugfs -R 'stat ' /dev/mapper/vg-root

输出可能如下所示:

debugfs -R 'stat ' /dev/mapper/vg-root

debugfs 1.41.12 (17-May-2010)
Inode: 94490   Type: regular    Mode:  0644   Flags: 0x0
Generation: 2826123170    Version: 0x00000000
User:     0   Group:     0   Size: 4441
File ACL: 0    Directory ACL: 0
Links: 1   Blockcount: 16
Fragment:  Address: 0    Number: 0    Size: 0
ctime: 0x5266e438 -- Wed Oct 23 09:46:48 2013
atime: 0x5266e47b -- Wed Oct 23 09:47:55 2013
mtime: 0x5266e438 -- Wed Oct 23 09:46:48 2013
Size of extra inode fields: 4
Extended attributes stored in inode body: 
  selinux = "unconfined_u:object_r:usr_t:s0\000" (31)
BLOCKS:
(0-1):375818-375819
TOTAL: 2

在哪里可以看到创建时间:

ctime: 0x5266e438 -- Wed Oct 23 09:46:48 2013

【讨论】:

ctime不是创建时间,是“文件状态信息最后修改时间” ctime = "更改时间" 其中更改意味着修改所有者、组、权限或其他一些属性。不一定是创建时间。【参考方案7】:

您可以使用 stat 查找创建时间(也称为出生时间),也可以使用 find 进行匹配。 我们有这些文件显示上次修改时间:

$ ls -l --time-style=long-iso | sort -k6
total 692
-rwxrwx---+ 1 XXXX XXXX 249159 2013-05-31 14:47 Getting Started.pdf
-rwxrwx---+ 1 XXXX XXXX 275799 2013-12-30 21:12 TheScienceofGettingRich.pdf
-rwxrwx---+ 1 XXXX XXXX  25600 2015-05-07 18:52 Thumbs.db
-rwxrwx---+ 1 XXXX XXXX 148051 2015-05-07 18:55 AsAManThinketh.pdf

使用 find 查找在特定时间范围内创建的文件,如下所示。 显然,文件系统知道文件的诞生时间:

$ find -newerBt '2014-06-13' ! -newerBt '2014-06-13 12:16:10' -ls 
20547673299906851  148 -rwxrwx---   1 XXXX XXXX   148051 May  7 18:55 ./AsAManThinketh.pdf
1407374883582246  244 -rwxrwx---   1 XXXX XXXX   249159 May 31  2013 ./Getting\ Started.pdf

我们可以使用 stat 来确认这一点:

$ stat -c "%w %n" * | sort
2014-06-13 12:16:03.873778400 +0100 AsAManThinketh.pdf
2014-06-13 12:16:04.006872500 +0100 Getting Started.pdf
2014-06-13 12:16:29.607075500 +0100 TheScienceofGettingRich.pdf
2015-05-07 18:32:26.938446200 +0100 Thumbs.db

stat 手册页解释 %w:

%w     time of file birth, human-readable; - if unknown

【讨论】:

似乎ls -l 显示的是修改时间,而不是创建或出生时间 $ /usr/bin/find -newerBt '2014-06-13' /usr/bin/find: This system does not provide a way to find the birth time of a file. /usr/bin/find: invalid predicate -newerBt'`【参考方案8】:

正如@mikyra 解释的那样,创建日期时间不会存储在任何地方。

上面所有的方法都不错,但是如果你想快速得到最后修改日期,你可以输入:

ls -lit /path

使用 -t 选项可以列出 /path 中按最后修改日期排序的所有文件。

【讨论】:

【参考方案9】:

如果你真的想实现这一点,你可以使用像 inotifywait 这样的文件观察器。

您观察一个目录并将有关文件创建的信息保存在该目录之外的单独文件中。

while true; do
  change=$(inotifywait -e close_write,moved_to,create .)
  change=$change#./ * 
  if [ "$change" = ".*" ]; then ./scriptToStoreInfoAboutFile; fi
done

由于不存储创建时间,您可以基于inotify构建自己的系统。

【讨论】:

【参考方案10】:

引用自 https://unix.stackexchange.com/questions/50177/birth-is-empty-on-ext4/131347#131347 ,以下 shellscript 可用于获取创建时间:

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

【讨论】:

不喜欢大多数人,因为它需要sudodebugfs【参考方案11】:
stat -c %w a.txt

%w 如果可用,则返回文件创建(出生)日期,这种情况很少见。

这是link

【讨论】:

【参考方案12】:

更好:

lsct () 
 
    debugfs -R 'stat <'`ls -i "$1" | (read a b;echo -n $a)`'>' `df "$1" | (read a; read a b; echo "$a")` 2> /dev/null | grep --color=auto crtime | ( read a b c d;
    echo $d )

lsct /etc

2016 年 7 月 20 日星期三 19:25:48

【讨论】:

【参考方案13】:

添加到您的武器库中的另一个技巧如下:

$ grep -r "Copyright" /<path-to-source-files>/src

一般来说,如果有人更改文件,他们应该在“版权”中声明功劳。检查日期、文件名、贡献者和联系电子邮件的结果。

示例 grep 结果:

/<path>/src/someobject.h: * Copyright 2007-2012 <creator's name> <creator's email>(at)<some URL>>

【讨论】:

以上是关于如何在 Bash/Debian 中获取文件创建日期/时间?的主要内容,如果未能解决你的问题,请参考以下文章

如何获取子目录中所有文件的创建日期[重复]

Python:如何获取文件夹的创建日期和时间? [复制]

如何从google驱动器存储中的文件中获取创建日期?

如何使用命令提示符复制在两个日期之间创建的所有文件?

OSX - 如何从命令行获取文件的创建和修改时间

LUA中如何获取文件创建时间和修改时间