A incapacidade de statmostrar o tempo de criação é devido à limitação da stat(2)chamada do sistema , cuja estrutura de retorno não incluiu um campo para o tempo de criação. A partir do Linux 4.11 (ou seja, 17.10 e mais recente *), no entanto, a nova statx(2)chamada do sistema está disponível, o que inclui um tempo de criação em sua estrutura de retorno.
* E possivelmente em versões mais antigas do LTS usando os kernels da pilha de habilitação de hardware (HWE). Verifique uname -rse você está usando um kernel pelo menos em 4.11 para confirmar.
Infelizmente, não é fácil fazer chamadas do sistema diretamente em um programa C. Normalmente, a glibc fornece um wrapper que facilita o trabalho, mas a glibc adicionou um wrapper apenas statx(2)em agosto de 2018 (versão 2.28 , disponível em 18.10). Felizmente, o @whotwagner escreveu um programa C de amostra que mostra como usar a statx(2)chamada do sistema nos sistemas x86 e x86-64. Sua saída é do mesmo formato que stato padrão, sem nenhuma opção de formatação, mas é simples modificá-la para imprimir apenas a hora do nascimento.
Primeiro, clone-o:
git clone https://github.com/whotwagner/statx-fun
Você pode compilar o statx.ccódigo ou, se desejar apenas a hora do nascimento, criar um birth.cno diretório clonado com o seguinte código (que é uma versão mínima da statx.cimpressão, apenas o carimbo de data / hora da criação, incluindo precisão de nanossegundos):
#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;
}
Então:
$ make birth
$ ./birth ./birth.c
1511793291.254337149
$ ./birth ./birth.c | xargs -I {} date -d @{}
Mon Nov 27 14:34:51 UTC 2017
Em teoria, isso deve tornar o tempo de criação mais acessível:
- mais sistemas de arquivos devem ser suportados do que apenas os ext * (
debugfsé uma ferramenta para sistemas de arquivos ext2 / 3/4 e inutilizável em outros)
- você não precisa do root para usá-lo (exceto para instalar alguns pacotes necessários, como
makee linux-libc-dev).
Testando um sistema xfs, por exemplo:
$ 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: -
No entanto, isso não funcionou para NTFS e exfat. Eu acho que os sistemas de arquivos FUSE para aqueles não incluíram o tempo de criação.
Se, ou melhor, quando, o glibc adicionar suporte à statx(2)chamada do sistema, statseguirá em breve e poderemos usar o statcomando antigo simples para isso. Mas acho que isso não será suportado nos lançamentos do LTS, mesmo que eles tenham novos kernels. Portanto, não espero que statem nenhuma versão atual do LTS (14.04, 16.04 ou 18.04) imprima o tempo de criação sem intervenção manual.
No 18.10, no entanto, você pode usar diretamente a statxfunção conforme descrito em man 2 statx(observe que a página de manual 18.10 está incorreta ao afirmar que a glibc ainda não adicionou o wrapper).