Không thể stat
hiển thị thời gian tạo là do giới hạn của lệnh stat(2)
gọi hệ thống , mà cấu trúc trả về không bao gồm một trường cho thời gian tạo. Tuy nhiên, bắt đầu với Linux 4.11 (tức là 17.10 và mới hơn *), cuộc gọi hệ thống mớistatx(2)
khả dụng, bao gồm thời gian tạo trong cấu trúc trả về của nó.
* Và có thể trên các bản phát hành LTS cũ hơn bằng cách sử dụng hạt nhân ngăn xếp phần cứng (HWE). Kiểm tra uname -r
xem nếu bạn đang sử dụng kernel ít nhất là 4.11 để xác nhận.
Thật không may, không dễ để gọi các cuộc gọi hệ thống trực tiếp trong một chương trình C. Thông thường glibc cung cấp một trình bao bọc giúp công việc trở nên dễ dàng, nhưng glibc chỉ thêm một trình bao bọc cho statx(2)
tháng 8 năm 2018 (phiên bản 2.28 , có sẵn trong 18.10). May mắn thay, @whotwagner đã viết một chương trình C mẫu cho biết cách sử dụng lệnh statx(2)
gọi hệ thống trên các hệ thống x86 và x86-64. Đầu ra của nó có cùng định dạng với stat
mặc định, không có bất kỳ tùy chọn định dạng nào, nhưng thật đơn giản để sửa đổi nó để chỉ in thời gian sinh.
Đầu tiên, sao chép nó:
git clone https://github.com/whotwagner/statx-fun
Bạn có thể biên dịch statx.c
mã, hoặc, nếu bạn chỉ muốn thời gian sinh, hãy tạo một birth.c
trong thư mục nhân bản với mã sau (đây là phiên bản tối thiểu của statx.c
việc in chỉ dấu thời gian tạo bao gồm độ chính xác nano giây)
#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;
}
Sau đó:
$ make birth
$ ./birth ./birth.c
1511793291.254337149
$ ./birth ./birth.c | xargs -I {} date -d @{}
Mon Nov 27 14:34:51 UTC 2017
Về lý thuyết, điều này sẽ làm cho thời gian sáng tạo dễ tiếp cận hơn:
- nhiều hệ thống tập tin nên được hỗ trợ hơn chỉ là hệ thống ext * (
debugfs
là công cụ dành cho hệ thống tập tin ext2 / 3/4 và không thể sử dụng trên các hệ thống khác)
- bạn không cần root để sử dụng cái này (ngoại trừ việc cài đặt một số gói bắt buộc, như
make
và linux-libc-dev
).
Thử nghiệm hệ thống xfs, ví dụ:
$ 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: -
Tuy nhiên, điều này không hoạt động đối với NTFS và exfat. Tôi đoán hệ thống tập tin FUSE cho những người không bao gồm thời gian tạo.
Nếu, hay đúng hơn là khi nào, glibc bổ sung hỗ trợ cho statx(2)
cuộc gọi hệ thống, stat
sẽ sớm xuất hiện và chúng tôi sẽ có thể sử dụng stat
lệnh cũ đơn giản cho việc này. Nhưng tôi không nghĩ rằng điều này sẽ được đưa vào các bản phát hành LTS ngay cả khi chúng có được các nhân mới hơn. Vì vậy, tôi không mong đợi stat
trên bất kỳ LTS phát hành hiện tại (14.04, 16.04 hoặc 18,04) bao giờ in thời gian sáng tạo mà không cần can thiệp bằng tay.
Tuy nhiên, vào ngày 18.10, bạn có thể trực tiếp sử dụng statx
chức năng như được mô tả trong man 2 statx
(lưu ý rằng trang chủ 18.10 không chính xác khi nói rằng glibc chưa thêm trình bao bọc).