Ketidakmampuan stat
untuk menunjukkan waktu pembuatan adalah karena keterbatasan stat(2)
panggilan sistem , yang kembali struct tidak menyertakan bidang untuk waktu pembuatan. Dimulai dengan Linux 4.11 (yaitu, 17.10 dan yang lebih baru *), bagaimanapun, panggilan sistem barustatx(2)
tersedia, yang tidak termasuk waktu pembuatan dalam struct kembali.
* Dan mungkin pada rilis LTS yang lebih lama menggunakan kernel enablement stack hardware (HWE). Periksa uname -r
untuk melihat apakah Anda menggunakan kernel setidaknya pada 4,11 untuk mengkonfirmasi.
Sayangnya, tidak mudah untuk memanggil panggilan sistem secara langsung dalam program C. Biasanya glibc menyediakan pembungkus yang memudahkan pekerjaan, tetapi glibc hanya menambahkan pembungkus untuk statx(2)
pada Agustus 2018 (versi 2.28 , tersedia dalam 18.10). Untungnya, @whotwagner menulis contoh program C yang menunjukkan cara menggunakan statx(2)
pemanggilan sistem pada sistem x86 dan x86-64. Outputnya adalah format yang sama dengan stat
default, tanpa opsi format apa pun, tetapi mudah untuk memodifikasinya untuk mencetak waktu kelahiran saja.
Pertama, klon:
git clone https://github.com/whotwagner/statx-fun
Anda dapat mengkompilasi statx.c
kode, atau, jika Anda hanya ingin waktu kelahiran, buat birth.c
di direktori kloning dengan kode berikut (yang merupakan versi minimal dari statx.c
pencetakan hanya cap waktu pembuatan termasuk ketepatan nanosecond):
#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;
}
Kemudian:
$ make birth
$ ./birth ./birth.c
1511793291.254337149
$ ./birth ./birth.c | xargs -I {} date -d @{}
Mon Nov 27 14:34:51 UTC 2017
Secara teori ini harus membuat waktu pembuatan lebih mudah diakses:
- lebih banyak filesystem yang harus didukung daripada hanya ext * (
debugfs
adalah alat untuk filesystem ext2 / 3/4, dan tidak dapat digunakan pada yang lain)
- Anda tidak perlu root untuk menggunakan ini (kecuali untuk menginstal beberapa paket yang diperlukan, seperti
make
dan linux-libc-dev
).
Menguji sistem xfs, misalnya:
$ 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: -
Namun, ini tidak berfungsi untuk NTFS dan exfat. Saya kira sistem file FUSE untuk mereka yang tidak termasuk waktu pembuatan.
Jika, atau lebih tepatnya kapan, glibc menambahkan dukungan untuk statx(2)
panggilan sistem, stat
akan segera menyusul dan kami akan dapat menggunakan perintah biasa stat
untuk ini. Tapi saya tidak berpikir ini akan di-backport ke rilis LTS bahkan jika mereka mendapatkan kernel yang lebih baru. Jadi, saya tidak berharap stat
pada rilis LTS saat ini (14,04, 16,04 atau 18,04) untuk pernah mencetak waktu pembuatan tanpa intervensi manual.
Pada 18.10, bagaimanapun, Anda dapat langsung menggunakan statx
fungsi seperti yang dijelaskan dalam man 2 statx
(perhatikan bahwa halaman 18.10 salah dalam menyatakan bahwa glibc belum menambahkan pembungkus).