L'impossibilité d' stat
afficher l'heure de création est due à la limitation de l' stat(2)
appel système , dont la structure de retour n'incluait pas de champ pour l'heure de création. À partir de Linux 4.11 (c'est-à-dire 17.10 et plus récent *), le nouvel statx(2)
appel système est disponible, ce qui inclut une heure de création dans sa structure de retour.
* Et éventuellement sur des versions antérieures de LTS utilisant les noyaux de pile d’activation matérielle (HWE). Vérifiez uname -r
si vous utilisez un noyau au moins à 4.11 pour confirmer.
Malheureusement, il n'est pas facile d'appeler des appels système directement dans un programme C. Glibc fournit généralement un wrapper qui facilite le travail, mais elle n’a ajouté un wrapper statx(2)
qu’en août 2018 (version 2.28 , disponible en 18.10). Heureusement, @whotwagner a écrit un exemple de programme en C qui montre comment utiliser l' statx(2)
appel système sur les systèmes x86 et x86-64. Sa sortie est au même format que celui stat
par défaut, sans aucune option de formatage, mais il est simple de le modifier pour n’imprimer que l’heure de naissance.
Commencez par le cloner:
git clone https://github.com/whotwagner/statx-fun
Vous pouvez compiler le statx.c
code ou, si vous voulez seulement l'heure de naissance, créer un birth.c
dans le répertoire cloné avec le code suivant (qui est une version minimale de l' statx.c
impression uniquement de l'horodatage de création avec une précision à la nanoseconde):
#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;
}
Ensuite:
$ make birth
$ ./birth ./birth.c
1511793291.254337149
$ ./birth ./birth.c | xargs -I {} date -d @{}
Mon Nov 27 14:34:51 UTC 2017
En théorie, cela devrait rendre le temps de création plus accessible:
- il convient de prendre en charge davantage de systèmes de fichiers que les seuls ext * (il
debugfs
s'agit d'un outil pour les systèmes de fichiers ext2 / 3/4 et inutilisable sur d'autres).
- vous n’avez pas besoin de root pour utiliser ceci (sauf pour installer certains paquets requis, comme
make
et linux-libc-dev
).
Tester un système xfs, par exemple:
$ 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: -
Cependant, cela n'a pas fonctionné pour NTFS et exfat. Je suppose que les systèmes de fichiers FUSE pour ceux-ci n'incluaient pas le temps de création.
Si, ou plutôt quand, glibc ajoute le support pour l' statx(2)
appel système, stat
suivra bientôt et nous pourrons utiliser la stat
commande plain old pour cela. Mais je ne pense pas que cela sera reporté dans les versions LTS, même s’ils obtiennent de nouveaux noyaux. Donc, je ne pense pas stat
à une version actuelle LTS (14,04, 16,04 ou 18,04) à jamais imprimer le temps de création sans intervention manuelle.
Toutefois, le 18.10, vous pouvez utiliser directement la statx
fonction comme décrit dans man 2 statx
(notez que la page de manuel 18.10 est incorrecte car elle indique que glibc n’a pas encore ajouté le wrapper).