在 Linux 上使用 Python 获取文件创建时间

Posted

技术标签:

【中文标题】在 Linux 上使用 Python 获取文件创建时间【英文标题】:Get file creation time with Python on linux 【发布时间】:2009-09-10 23:35:39 【问题描述】:

os.stat 返回 st_mtime 和 st_ctime 属性,修改时间是 st_mtime 和 st_ctime 在 POSIX 上的“更改时间”。 有没有使用python和Linux下返回文件创建时间的函数?

【问题讨论】:

这对我有用:***.com/a/947239/4535020 看起来这取决于您使用的文件系统:unix.stackexchange.com/questions/7562/… 【参考方案1】:

You probablycan't.:

3.1)  How do I find the creation time of a file?

      You can't - it isn't stored anywhere.  Files have a last-modified
      time (shown by "ls -l"), a last-accessed time (shown by "ls -lu")
      and an inode change time (shown by "ls -lc"). The latter is often
      referred to as the "creation time" - even in some man pages -
      but that's wrong; it's also set by such operations as mv, ln,
      chmod, chown and chgrp.

      The man page for "stat(2)" discusses this.

【讨论】:

那么如果 stat 没有,是否有命令在 Linux 中查找文件创建的时间和日期? 一般来说,UNIX 文件系统根本不存储创建时间——没有办法检索从一开始就没有写入磁盘的数据。 Most newer fs's do now support creation/birth time. 截至 2019 年 3 月,Linux 内核、glibc 和 coreutils 支持 statx()crtime【参考方案2】:

尝试:

st_birthtime

但它不能保证在所有系统上都可用。来自文档:

在某些 Unix 系统(如 Linux)上, 以下属性也可能是 可用:st_blocks(块数 分配给文件),st_blksize (文件系统块大小),st_rdev(类型 如果是 inode 设备,则为设备)。 st_flags(用户定义的标志 文件)。

在其他 Unix 系统上(例如 FreeBSD),以下属性可能 可用(但可能只填写 如果 root 尝试使用它们,则退出):st_gen (文件代号),st_birthtime (文件创建时间)。

http://docs.python.org/2/library/os.html#os.stat

【讨论】:

【参考方案3】:

由于缺乏好的实用程序,我创建了crtime。

pip install crtime

然后你可以像这样使用它:

sudo crtime ./

将打印:

1552938281  /home/pascal/crtime/.gitignore
1552938281  /home/pascal/crtime/README.md
1552938281  /home/pascal/crtime/crtime
1552938281  /home/pascal/crtime/deploy.py
1552938281  /home/pascal/crtime/setup.cfg
1552938281  /home/pascal/crtime/setup.py
1552938961  /home/pascal/crtime/crtime.egg-info
1552939447  /home/pascal/crtime/.git
1552939540  /home/pascal/crtime/build
1552939540  /home/pascal/crtime/dist

请注意,对于大型目录,它会比上面的 xstat 快 1000 倍,因为这会创建一个临时文件,然后一次对所有文件执行 stat 调用。

在 python 中(别忘了你还需要在 linux 上用 sudo 调用它):

from crtime import get_crtimes, get_crtimes_in_dir
get_crtimes_in_dir("./")

【讨论】:

【参考方案4】:

根据here 的线程,OS X 的 HFS 和 Microsoft 的 NTFS 也都跟踪出生时间,我被告知 OS X 和 Cygwin 版本的 stat() 返回此信息。查看osx stat manpage 至少对于mac来说似乎是正确的:

a、m、c、B

上次访问或修改文件的时间,上次更改 inode 的时间,或 inode 的诞生时间

对于像 ext4、Btrfs 和 JFS 这样的 linux 较新的文件系统,使用 debugfs 确实支持这一点,有一个取自 here 的 bash 函数将提取日期创建的时间戳

如果您处理功能强大的文件系统(如 EXT4 - Linux 日志文件系统),您可以恢复文件创建日期:

改进的时间戳

... Ext4 提供以纳秒为单位的时间戳。此外,ext4 还增加了对日期创建时间戳的支持。 但是社区对此没有达成共识

...正如 Theodore Ts'o 指出的那样,虽然在 inode 中添加额外的创建日期字段很容易(因此在技术上支持在 ext4 中创建日期时间戳),但修改或添加必要的系统调用,如 stat()(可能需要新版本)和依赖它们的各种库(如 glibc)。这些变化需要协调许多项目。因此,即使 ext4 开发人员实现了对创建日期时间戳的初始支持,用户程序现在也无法使用此功能。 最后是 Linus 的最终报价

让我们等五年,看看是否真的就需要和使用它达成共识,而不是仅仅因为“我们可以”就急于做某事。

xstat() 
  for target in "$@"; do
    inode=$(ls -di "$target" | cut -d ' ' -f 1)
    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" "$crtime" "$target"
  done

运行它会返回创建日期:

:~$ echo 'print("hello world")' > blah.py
:~$ xstat "blah.py"
Mon Jul  6 13:43:39 2015    blah.py
:~$ echo 'print("goodbye world")' > blah.py
:~$ xstat "blah.py"
Mon Jul  6 13:43:39 2015    blah.py

因此,除非文件系统支持,否则这是不可能的,如果文件系统支持,那么您可以使用子进程运行 debugfs 并解析输出。

【讨论】:

【参考方案5】:

您可能会解释为什么要这样做。

一种间接的解决方案可能是使用一些revision control 系统(又名版本控制系统 = VCS)来管理需要其出生时间的文件。

因此您可以在此类文件上使用git(即将它们作为“源代码”处理)。然后你不仅知道它们是什么时候创建的(实际上是使用git add 在 VCS 中注册的),而且知道为什么、由谁、为了什么等等......使用git log 来获取所有这些......

当然,您需要以某种方式教育您的用户使用像 git 这样的 VCS

【讨论】:

【参考方案6】:

某些文件系统确实支持记录出生时间,但 Linux 不提供获取它的接口。

见http://lwn.net/Articles/397442/

如果尝试使用“stat”命令获取它: % stat -c %w 文件或目录

结果将是“-”,因为它无法检索它。但是,可以使用这个示例方法,利用带有 xstat 的 debugfs 来检索它(再次假设正在使用的文件系统支持收集它。)

https://gist.github.com/moiseevigor/8c496f632137605b322e

xstat() 
  for target in "$@"; do
    inode=$(ls -di "$target" | cut -d ' ' -f 1)
    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" "$crtime" "$target"
  done

注意这需要 sudo。

【讨论】:

自 2019 年 3 月起,Linux 现在通过内核、glibc 和 coreutils 中的 statx() 支持它。【参考方案7】:

你是什么意思它不能完成[1]?函数,

os.stat(path).st_birthtime
,效果很好。 [1]: 有人说做不到 但他笑着回答 那个“也许不能”,但他会是一个 在他尝试之前谁不会这么说。 于是,他带着一丝笑容直接扣住了 在他的脸上。如果他担心,他会隐藏它。 他在处理这件事时开始唱歌 那是做不到的,他做到了! ——埃德加·阿尔伯特·盖斯特

【讨论】:

那是什么?你的回答令人困惑。

以上是关于在 Linux 上使用 Python 获取文件创建时间的主要内容,如果未能解决你的问题,请参考以下文章

Linux上使用Python进行数据处理

Linux上搭建文件浏览的web服务(创建软件仓库)

有没有办法获取使用 python 创建文件的年份? [复制]

[Python]-10-文件读写(上)

如何使用 Pyinstaller 为 Linux 机器创建可执行文件?

oldboy.32-python程序在linux上面的创建与执行