Yetersizlik stat
yaratma zamanı göstermek için bir sınırlama kaynaklanmaktadır stat(2)
sistem çağrısı dönüş yapı oluşturma zaman için bir alan içermiyordu. Bununla birlikte, Linux 4.11'den başlayarak (yani, 17.10 ve daha yeni *), ancak geri dönüş yapısında bir oluşturma zamanı içeren yeni statx(2)
sistem çağrısı kullanılabilir.
* Büyük olasılıkla daha eski LTS sürümlerinde donanım etkinleştirme yığını (HWE) çekirdeklerini kullanarak. uname -r
Onaylamak için en az 4.11'de bir çekirdek kullanıp kullanmadığınızı kontrol edin .
Ne yazık ki, sistem çağrılarını doğrudan bir C programında çağırmak kolay değildir. Genellikle glibc, işi kolaylaştıran bir sarıcı sağlar, ancak glibc yalnızca statx(2)
Ağustos 2018'deki bir sarıcıyı ekler (sürüm 2.28 , 18.10'da bulunur). Neyse ki, @whotwagner , x86 ve x86-64 sistemlerinde sistem çağrısının nasıl kullanılacağını gösteren örnek bir C programı yazdı statx(2)
. Çıktı stat
, herhangi bir biçimlendirme seçeneği olmadan varsayılanla aynıdır , ancak yalnızca doğum zamanını yazdırmak için değiştirmek kolaydır.
İlk önce, onu kopyalayın:
git clone https://github.com/whotwagner/statx-fun
statx.c
Kodu derleyebilir veya yalnızca doğum saatini istiyorsanız birth.c
, aşağıdaki kodla klonlanmış bir dizinde bir dizin oluşturabilirsiniz (bu, statx.c
nanosaniye kesinliği dahil yalnızca oluşturma zaman damgasının yazdırılmasının minimal bir sürümüdür ):
#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;
}
Sonra:
$ make birth
$ ./birth ./birth.c
1511793291.254337149
$ ./birth ./birth.c | xargs -I {} date -d @{}
Mon Nov 27 14:34:51 UTC 2017
Teoride bu, yaratma zamanını daha erişilebilir hale getirmelidir:
- ext * olanlardan daha fazla dosya sistemi desteklenmelidir (
debugfs
ext2 / 3/4 dosya sistemleri için bir araçtır ve diğerleri için kullanılamaz)
- Bunu kullanmak için root kullanmanıza gerek yoktur (
make
ve gibi bazı gerekli paketleri kurmak dışında linux-libc-dev
).
Bir xfs sistemini test etmek, örneğin:
$ 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: -
Ancak, bu NTFS ve exfat için işe yaramadı. Sanırım bunlar için FUSE dosya sistemleri oluşturma zamanını içermiyordu.
Eğer, ya da daha doğrusu, glibc statx(2)
sistem çağrısı için destek eklerse , stat
yakında takip eder ve bunun için düz eski stat
komutu kullanabiliriz . Ancak bunun, daha yeni çekirdek alsalar bile, LTS sürümlerine destekleneceğini sanmıyorum. Yani, beklemeyin stat
üzerinde herhangi bir geçerli LTS sürümü şimdiye manuel müdahale olmadan oluşturma süresini yazdırmak için (14.04, 16.04 veya 18.04).
Bununla birlikte, 18.10'da, statx
işlevi açıklandığı şekilde doğrudan kullanabilirsiniz man 2 statx
(18.10 kılavuz sayfasının, glibc'nin henüz sarıcıyı eklemediğini belirtmekte yanlış olduğunu unutmayın).