Como encontrar a data de criação do arquivo?

98

Eu quero descobrir a data de criação do arquivo em particular, não a data de modificação ou a data de acesso.

Eu tentei com ls -ltrh e stat filename .

    
por Özzesh 18.09.2013 / 06:44

7 respostas

82

O padrão POSIX define a"penas a"s três timestamps distintos a" serem a"rmazenados para cada a"rquivo: a" hora do último a"cesso a" dados, a" hora da última modificação de dados e a" hora em que o status do a"rquivo foi a"lterado pela última vez.

Dito isto, sistemas de a"rquivos Linux modernos, como ext4, Btrfs e JFS, a"rmazenam o tempo de criação do a"rquivo (aka birth time), mas usam nomes diferentes para o campo em questão ( crtime in ext4, otime em Btrfs e JFS). No entanto, a"tualmente o Linux não fornece uma API do kernel para a"cessar os tempos de criação de a"rquivos , mesmo em sistemas de a"rquivos que os suportam.

Como Craig Sanders e Mohsen Pahlevanzadeh a"pontou, stat suporta os %w e %W de especificadores de formato para exibir o horário de nascimento do a"rquivo (em formato legível por humanos e em segundos desde Epoch, respectivamente). No entanto, stat a"cessa o horário de nascimento por meio do get_stat_birthtime() fornecido pelo gnulib (em lib/stat-time.h ), que obtém o tempo de nascimento dos campos st_birthtime e st_birthtimensec da estrutura stat retornada pelo stat() chamada do sistema. Enquanto, por exemplo, os sistemas BSD (e na extensão OS X) fornecem st_birthtime via stat , o Linux não. É por isso que stat -c '%w' file outputs - (indicando um tempo de criação desconhecido) no Linux, mesmo para sistemas de a"rquivos que a"rmazenam o tempo de criação internamente.

Como Stephane Chazelas destaca , a"lguns sistemas de a"rquivos, como o ntfs-3g, expõem os tempos de criação do a"rquivo por meio de a"tributos de a"rquivo estendidos.

    
por 18.09.2013 / 07:00
24

TLDR; Use stap ( "SystemTap" ) para criar sua própria API do kernel. Demonstração da extração do tempo de criação do ext4 abaixo.

Você pode extrair os tempos de criação do ext4 nos sistemas Fedora 19. Aqui está o meu:

$ uname -a
Linux steelers.net 3.11.1-200.fc19.i686.PAE #1 SMP Sat Sep 14 15:20:42 UTC 2013 i686 i686 i386 GNU/Linux

É claro que os inodes nas minhas partições ext4 têm o tempo de criação. Aqui está um script de shell que determina o inode associado a um nome de arquivo e, em seguida, aumenta a stat output com o tempo de criação usando stap ("systemtap").

NB: Esta é apenas uma demonstração e imensamente ineficiente desde que um módulo do kernel é criado, carregado e descarregado para cada execução. Isso também é provavelmente muito frágil, pois nenhuma verificação de erros é executada. Uma API do kernel adequada seria preferível, mas esse script poderia ser muito mais eficiente e ler os tempos de criação de vários arquivos / inodes.

[conteúdo do stap_stat.sh]

#/bin/sh

my_inode_str=$(stat --printf="%i" $1)

stap - << end_of_stap_script
global my_offsetof
probe begin {
  system("stat $1");
  my_offsetof = &@cast(0,"struct ext4_inode_info")->vfs_inode;
}
probe kernel.function("ext4_getattr@fs/ext4/inode.c") {
  probe_inode=\$dentry->d_inode;
  if (@cast(probe_inode, "struct inode")->i_ino == $my_inode_str) {
    my_i_crtime = &@cast(probe_inode - my_offsetof,"struct ext4_inode_info")->i_crtime;
    printf("CrTime: %s GMT\n", ctime(@cast(my_i_crtime, "timespec")->tv_sec));
    printf("CrTime (nsecs): %d\n", @cast(my_i_crtime, "timespec")->tv_nsec);
    exit();
  }
}
end_of_stap_script

Aqui está uma demonstração:

$ ll testfile
ls: cannot access testfile: No such file or directory
$ touch testfile
$ ./stap_stat.sh testfile
  File: ‘testfile’
  Size: 0           Blocks: 0          IO Block: 4096   regular empty file
Device: fd02h/64770d    Inode: 4850501     Links: 1
Access: (0664/-rw-rw-r--)  Uid: ( 1001/    Rick)   Gid: ( 1001/    Rick)
Context: unconfined_u:object_r:user_home_t:s0
Access: 2013-09-28 06:17:04.221441084 -0400
Modify: 2013-09-28 06:17:04.221441084 -0400
Change: 2013-09-28 06:17:04.221441084 -0400
 Birth: -
CrTime: Sat Sep 28 10:17:04 2013 GMT
CrTime (nsecs): 220441085
$ ll testfile
-rw-rw-r--. 1 Rick Rick 0 Sep 28 06:17 testfile
$ cat - >> testfile 
Now is the time ...
$ ll testfile 
-rw-rw-r--. 1 Rick Rick 20 Sep 28 06:18 testfile
$ ./stap_stat.sh testfile
  File: ‘testfile’
Device: fd02h/64770d    Inode: 4850501     Links: 1
Access: (0664/-rw-rw-r--)  Uid: ( 1001/    Rick)   Gid: ( 1001/    Rick)
Context: unconfined_u:object_r:user_home_t:s0
Access: 2013-09-28 06:17:04.221441084 -0400
Modify: 2013-09-28 06:18:33.684374740 -0400
Change: 2013-09-28 06:18:33.684374740 -0400
 Birth: -
CrTime: Sat Sep 28 10:17:04 2013 GMT
CrTime (nsecs): 220441085
$ cat testfile 
Now is the time ...
$ ./stap_stat.sh testfile
  File: ‘testfile’
  Size: 20          Blocks: 8          IO Block: 4096   regular file
Device: fd02h/64770d    Inode: 4850501     Links: 1
Access: (0664/-rw-rw-r--)  Uid: ( 1001/    Rick)   Gid: ( 1001/    Rick)
Context: unconfined_u:object_r:user_home_t:s0
Access: 2013-09-28 06:19:12.199349463 -0400
Modify: 2013-09-28 06:18:33.684374740 -0400
Change: 2013-09-28 06:18:33.684374740 -0400
 Birth: -
CrTime: Sat Sep 28 10:17:04 2013 GMT
CrTime (nsecs): 220441085
$ mv testfile testfile2
$ ./stap_stat.sh testfile2 
  File: ‘testfile2’
  Size: 20          Blocks: 8          IO Block: 4096   regular file
Device: fd02h/64770d    Inode: 4850501     Links: 1
Access: (0664/-rw-rw-r--)  Uid: ( 1001/    Rick)   Gid: ( 1001/    Rick)
Context: unconfined_u:object_r:user_home_t:s0
Access: 2013-09-28 06:19:12.199349463 -0400
Modify: 2013-09-28 06:18:33.684374740 -0400
Change: 2013-09-28 06:20:45.870295668 -0400
 Birth: -
CrTime: Sat Sep 28 10:17:04 2013 GMT
CrTime (nsecs): 220441085
$ 
    
por 28.09.2013 / 12:30
17

Em ext4 é possível; porque ext4 file-system armazena o tempo de criação do arquivo. Mas ainda assim, você descobrirá que o comando stat não pode mostrar a data, porque acho que o kernel não está tendo APIs para isso.

De qualquer forma, a hora de nascimento do arquivo é armazenada em ext4 e você pode encontrá-lo, embora não por um método direto, mas usando debugfs

sudo debugfs -R "stat /ABSOLUTE/PATH" /dev/sdxX | grep crtime

    
por 14.09.2014 / 15:43
15

Em teoria, com o GNU stat você pode usar stat -c '%w' ou %W para obter a data de criação de um arquivo (também conhecido como birthtime).

Na prática, a maioria dos sistemas de arquivos não registra essas informações e o kernel do Linux não fornece nenhuma maneira de acessá-las.

O mais próximo que você pode obter é o ctime do arquivo, que não é o horário em que os metadados do arquivo foram alterados pela última vez.

Linux Weekly News teve um artigo interessante sobre isso alguns anos atrás - link

    
por 18.09.2013 / 07:02
7
stat --printf='%w' yourfile   #human readable

stat --printf='%W' yourfile   #seconds from Epoch , 0 if unknown

Diferença entre FreeBSD e GNU\Linux on stat command :

Se você chamar o comando stat em GNU\Linux ele invoca a opção -x , mas no FreeBSD, você mesmo deve invocar a opção -x .

Veja também Quais sistemas de arquivos no Linux armazenam o tempo de criação?

Notas: --printf é muito útil em scripting ....!

    
por 18.09.2013 / 08:35
5

No OS X, você pode usar ls -lU , stat -f%B , GetFileInfo -d ou mdls -n kMDItemFSCreationDate :

$ ls -lU
total 0
-rw-r--r--  1 lauri  staff  0 Apr 25 03:58 a
$ stat -f%B a
1398387538
$ stat -f%SB -t %Y%m%d%H%M a
201404250358
$ GetFileInfo -d a
04/25/2014 03:58:58
$ mdls -n kMDItemFSCreationDate a
kMDItemFSCreationDate = 2014-04-25 00:58:58 +0000
    
por 25.04.2014 / 03:07
2

Verifique isso:

# the last arg is the device to scan in.
debugfs -R 'stat /home/renich/somefile' /dev/sda1

BTW, isso funciona apenas no ext4. Eu não encontrei uma solução para o BtrFS ... ainda;)

    
por 29.12.2015 / 00:40