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

104

Quero descobrir a data de criação de um arquivo específico, não a data de modificação ou data de acesso.

Eu tentei com ls -ltrhe stat filename.

Özzesh
fonte
5
O Linux não controla o tempo de criação, pois não é exigido pelo POSIX. No entanto, o Mac OS X funciona com o sistema de arquivos HFS - procure em "hora do nascimento" em stat(1).
200_success 18/09/13
2
Os sistemas de arquivos ext4 do Fedora 19 definem os tempos de criação do arquivo. Tenho certeza de que existem muitos outros exemplos. Veja a resposta abaixo usada stappara recuperar os tempos de criação.
rickhg12hs

Respostas:

88

O padrão POSIX define apenas três carimbos de data / hora distintos a serem armazenados para cada arquivo: a hora do último acesso aos dados, a hora da última modificação dos dados e a hora em que o status do arquivo foi alterado pela última vez.

Dito isto, os sistemas de arquivos modernos do Linux, como ext4, Btrfs e JFS, armazenam o tempo de criação do arquivo (também conhecido como tempo de nascimento), mas usam nomes diferentes para o campo em questão ( crtimeno ext4, otimeno Btrfs e no JFS). No entanto, atualmente o Linux não fornece uma API do kernel para acessar os horários de criação do arquivo , mesmo nos sistemas de arquivos que os suportam.

Como Craig Sanders e Mohsen Pahlevanzadeh apontaram, statsuporta os especificadores %we de %Wformato para exibir o tempo de nascimento do arquivo (em formato legível por humanos e em segundos desde a Epoch, respectivamente). No entanto, statele próprio acessa a hora do nascimento por meio do get_stat_birthtime()gnulib (in lib/stat-time.h), que obtém a hora do nascimento dos campos st_birthtimee st_birthtimensecda statestrutura retornada pela stat()chamada do sistema. Enquanto, por exemplo, os sistemas BSD (e na extensão OS X) fornecem st_birthtimevia stat, o Linux não fornece. É por isso que as stat -c '%w' filesaídas -(indicando um tempo de criação desconhecido) no Linux, mesmo para sistemas de arquivos que armazenam o tempo de criação internamente.

Como Stephane Chazelas aponta , alguns sistemas de arquivos, como o ntfs-3g, expõem os tempos de criação do arquivo por meio de atributos de arquivo estendidos.

Thomas Nyman
fonte
4
No Linux, agora é armazenado em muitos sistemas de arquivos, incluindo ext4. Ainda não existe uma API do kernel para obtê-lo. Alguns sistemas de arquivos como NTFS-3G mais fusível torná-lo disponível por meio da API atributo estendido
Stéphane Chazelas
@StephaneChazelas Obrigado por seus comentários. Atualizado a resposta para fornecer mais detalhes.
Thomas Nyman
Você pode usar stappara criar sua própria API do kernel. Veja o exemplo na resposta aqui.
rickhg12hs
26

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

Você pode extrair os tempos de criação 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 aumenta a statsaída com o tempo de criação usando stap("systemtap").

Nota: Esta é apenas uma demonstração e extremamente ineficiente, pois 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 erro é realizada. Uma API apropriada do kernel 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 de 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
$ 
rickhg12hs
fonte
4
Ok, isso é legal. +1 por usar o stap, macaco corrigindo o kernel do linux, incrível.
Chris Magnuson
@ ChrisMagnuson: debugfs + statpermite obter crtimesem que o patch do macaco seja executado .
jfs
17

Em ext4que é possível; porque ext4o sistema de arquivos armazena o tempo de criação do arquivo. Mas, ainda assim, você descobrirá que o statcomando não pode mostrar a data, porque acho que o kernel não está tendo nenhuma API para isso.

De qualquer forma, o tempo de nascimento do arquivo é armazenado ext4e você pode descobrir, embora não por um método direto, mas usandodebugfs

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

iniciante
fonte
11
como uma função bash:xstat filename
jfs 26/07
11
Se /dev/sdxXestiver montado /some/pathe o arquivo estiver /some/path/some/file, o caminho a ser especificado é apenas some/file: seu caminho deve ser referido não à raiz do sistema de arquivos, mas ao ponto de montagem. Caso contrário, o arquivo não será encontrado.
BowPark
15

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

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 chegar é o ctime do arquivo, que não é o horário da criação, é o horário em que os metadados do arquivo foram alterados pela última vez.

O Linux Weekly News teve um artigo interessante sobre isso alguns anos atrás - http://lwn.net/Articles/397442/

cas
fonte
7
stat --printf='%w' yourfile   #human readable

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

Diferença entre FreeBSDe GNU\Linuxsobre stat command:

Se você chamar statcommand, GNU\Linuxele invoca a -x opção, mas no FreeBSD, você mesmo deve invocar a -xopção.

Consulte também Quais sistemas de arquivos no Linux armazenam o horário da criação?

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

PersianGulf
fonte
//, Tentei isso em uma máquina CEntOS 6 e tudo o que obtive foram pontos de interrogação: $ stat --printf = '% w' ~ / dump.rdb? Talvez meu sistema de arquivos não suporte stat com% w.
Nathan Basanese
infelizmente, o HFS não suporta ctime.
precisa saber é o seguinte
5

Em OS X pode utilizar ls -lU, stat -f%B, GetFileInfo -dou 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
Lri
fonte
2

Veja isso:

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

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

Renich
fonte
11
Isso é basicamente o que a resposta do iniciante diz ... não é?
31515 don_crissti
whoops, você está @don_crissti direito
Renich