当我阅读有关此问题的一些文章时,我需要查找文件的创建时间,所有文章都提到没有解决方案(例如Site1,Site2)。
当我尝试该stat
命令时,它显示为 Birth: -
。
那么,如何找到文件的创建时间呢?
当我阅读有关此问题的一些文章时,我需要查找文件的创建时间,所有文章都提到没有解决方案(例如Site1,Site2)。
当我尝试该stat
命令时,它显示为 Birth: -
。
那么,如何找到文件的创建时间呢?
Answers:
有一种方法可以知道目录的创建日期,只需执行以下步骤:
通过命令知道目录的索引节点ls -i
(例如说它的X)
知道目录是通过df -T /path
命令保存在哪个分区上的(假设它在on上 /dev/sda1
)
现在使用以下命令: sudo debugfs -R 'stat <X>' /dev/sda1
您将在输出中看到:
crtime: 0x4e81cacc:966104fc -- mon Sep 27 14:38:28 2013
crtime 是文件的创建日期。
我测试了什么:
通过创建文件对其进行了修改。
我尝试了命令,它给出了确切的时间。
statx()
截至2019
@Nux为此找到了一个不错的解决方案,所有人都应该赞成。我决定编写一个小函数,可以直接运行所有函数。只需将此添加到您的
~/.bashrc
。
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
}
现在,您可以运行get_crtime
以打印任意数量的文件或目录的创建日期:
$ get_crtime foo foo/file
foo Wed May 21 17:11:08 2014
foo/file Wed May 21 17:11:27 2014
cp -p
或类似方式创建副本,否则它将设置为创建副本的那一刻。
df
似乎不支持该--output
选项。在这种情况下,您可以用替换该行,fs=$(df foo | awk '{a=$1}END{print a}'
该功能也将正常工作。我在此答案中显示的是一种将可以直接对文件/目录目标运行的方式包装已接受答案中的命令的方法。
无法stat
显示创建时间是由于stat(2)
系统调用的限制,系统调用的返回结构未包含创建时间字段。但是,从Linux 4.11(即17.10和更高版本*)开始,可以使用新的statx(2)
系统调用,该调用的返回结构中确实包含创建时间。
*并且可能在使用硬件启用堆栈(HWE)内核的较早的LTS版本中。检查uname -r
是否至少在4.11上使用内核以进行确认。
不幸的是,在C程序中直接调用系统调用并不容易。通常,glibc提供了一个使工作轻松的包装器,但是glibc仅statx(2)
在2018年8月添加了一个包装器(版本2.28,在18.10中可用)。幸运的是,@ whotwagner编写了一个示例C程序,该程序演示了如何statx(2)
在x86和x86-64系统上使用系统调用。其输出格式与stat
默认格式相同,没有任何格式设置选项,但修改它以仅打印出生时间很简单。
首先,克隆它:
git clone https://github.com/whotwagner/statx-fun
您可以编译statx.c
代码,或者,如果您只想要出生时间,请birth.c
使用以下代码在克隆的目录中创建一个(这是statx.c
仅打印创建时间戳(包括纳秒精度)的最小版本):
#define _GNU_SOURCE
#define _ATFILE_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>
#include <fcntl.h>
#include "statx.h"
#include <time.h>
#include <getopt.h>
#include <string.h>
// does not (yet) provide a wrapper for the statx() system call
#include <sys/syscall.h>
/* this code works ony with x86 and x86_64 */
#if __x86_64__
#define __NR_statx 332
#else
#define __NR_statx 383
#endif
#define statx(a,b,c,d,e) syscall(__NR_statx,(a),(b),(c),(d),(e))
int main(int argc, char *argv[])
{
int dirfd = AT_FDCWD;
int flags = AT_SYMLINK_NOFOLLOW;
unsigned int mask = STATX_ALL;
struct statx stxbuf;
long ret = 0;
int opt = 0;
while(( opt = getopt(argc, argv, "alfd")) != -1)
{
switch(opt) {
case 'a':
flags |= AT_NO_AUTOMOUNT;
break;
case 'l':
flags &= ~AT_SYMLINK_NOFOLLOW;
break;
case 'f':
flags &= ~AT_STATX_SYNC_TYPE;
flags |= AT_STATX_FORCE_SYNC;
break;
case 'd':
flags &= ~AT_STATX_SYNC_TYPE;
flags |= AT_STATX_DONT_SYNC;
break;
default:
exit(EXIT_SUCCESS);
break;
}
}
if (optind >= argc) {
exit(EXIT_FAILURE);
}
for (; optind < argc; optind++) {
memset(&stxbuf, 0xbf, sizeof(stxbuf));
ret = statx(dirfd, argv[optind], flags, mask, &stxbuf);
if( ret < 0)
{
perror("statx");
return EXIT_FAILURE;
}
printf("%lld.%u\n", *&stxbuf.stx_btime.tv_sec, *&stxbuf.stx_btime.tv_nsec);
}
return EXIT_SUCCESS;
}
然后:
$ make birth
$ ./birth ./birth.c
1511793291.254337149
$ ./birth ./birth.c | xargs -I {} date -d @{}
Mon Nov 27 14:34:51 UTC 2017
从理论上讲,这应该使创建时间更容易访问:
debugfs
是ext2 / 3/4文件系统的工具,在其他系统上不可用)make
和linux-libc-dev
)。测试xfs系统,例如:
$ truncate -s 1G temp; mkfs -t xfs temp; mkdir foo; sudo mount temp foo; sudo chown $USER foo
$ touch foo/bar
$ # some time later
$ echo > foo/bar
$ chmod og-w foo/bar
$ ./birth foo/bar | xargs -I {} date -d @{}
Mon Nov 27 14:43:21 UTC 2017
$ stat foo/bar
File: foo/bar
Size: 1 Blocks: 8 IO Block: 4096 regular file
Device: 700h/1792d Inode: 99 Links: 1
Access: (0644/-rw-r--r--) Uid: ( 1000/ muru) Gid: ( 1000/ muru)
Access: 2017-11-27 14:43:32.845579010 +0000
Modify: 2017-11-27 14:44:38.809696644 +0000
Change: 2017-11-27 14:44:45.536112317 +0000
Birth: -
但是,这不适用于NTFS和exfat。我猜那些的FUSE文件系统不包括创建时间。
如果glibc添加了对statx(2)
系统调用的支持,或者将在以后发布,那么stat
我们将能够使用普通的旧stat
命令。但是我不认为这会被移植到LTS版本中,即使它们确实获得了更新的内核。因此,我不希望stat
在任何当前的LTS版本(14.04、16.04或18.04)上打印创建时间而无需人工干预。
但是,在18.10上,您可以statx
按照所述直接使用该函数man 2 statx
(请注意,18.10联机帮助页指出glibc尚未添加包装器是不正确的)。
1
?
TL; DR:
只需运行:
sudo debugfs -R 'stat /path/to/your/file' /dev/<your fs>
(要弄清楚您的fs,请运行df -T /path/to/your/file
,很可能是/dev/sda1
)。
长版:
我们将运行两个命令:
找出文件的分区名称的名称。
df -T /path/to/your/file
输出将如下所示(分区名称为第一):
Filesystem Type 1K-blocks Used Available Use% Mounted on
/dev/<your fs> ext4 7251432 3481272 3509836 50% /
找出该文件的创建时间。
sudo debugfs -R 'stat /path/to/your/file' /dev/<your fs>
在输出中,查找ctime
。