Comment trouver la date de création du fichier?

104

Je souhaite connaître la date de création d'un fichier particulier, et non la date de modification ou la date d'accès.

J'ai essayé avec ls -ltrhet stat filename.

Özzesh
la source
5
Linux ne garde pas trace du moment de la création car il n’est pas requis par POSIX. Cependant, Mac OS X utilise le système de fichiers HFS - regardez sous "heure de naissance" dans stat(1).
200_success
2
Les systèmes de fichiers Fedora 19 ext4 définissent les heures de création des fichiers. Je suis sûr qu'il y a beaucoup plus d'exemples. Voir la réponse ci-dessous qui utilise stappour récupérer les temps de création.
rickhg12hs

Réponses:

88

La norme POSIX ne définit que trois horodatages distincts à stocker pour chaque fichier: l'heure du dernier accès aux données, l'heure de la dernière modification des données et l'heure de la dernière modification du statut du fichier.

Cela dit, les systèmes de fichiers Linux modernes, tels que ext4, Btrfs et JFS, enregistrent l'heure de création du fichier (heure de naissance), mais utilisent des noms différents pour le champ en question ( crtimedans ext4, otimedans Btrfs et JFS). Cependant, actuellement, Linux ne fournit pas d’API de noyau pour accéder aux temps de création de fichiers , même sur les systèmes de fichiers les prenant en charge.

Comme Craig Sanders et Mohsen Pahlevanzadeh ont souligné, statne supporte le %wet %Wspécificateurs de format pour afficher l'heure de naissance de fichier (en format lisible par l' homme et en quelques secondes depuis Epoch respectivement). Cependant, statlui - même accède à l'heure de naissance via la fonction get_stat_birthtime()fournie par gnulib (in lib/stat-time.h), qui obtient l'heure de naissance à partir des champs st_birthtimeet st_birthtimensecde la statstructure renvoyés par l' stat()appel système. Bien que, par exemple, les systèmes BSD (et, par extension, OS X) fournissent st_birthtimevia stat, ce n’est pas le cas de Linux. C’est pourquoi les stat -c '%w' filesorties -(indiquant une heure de création inconnue) sous Linux, même pour les systèmes de fichiers qui stockent l’heure de création en interne.

Comme le souligne Stéphane Chazelas , certains systèmes de fichiers, tels que ntfs-3g, exposent les temps de création de fichiers via des attributs de fichier étendus.

Thomas Nyman
la source
4
Sous Linux, il est maintenant stocké dans de nombreux systèmes de fichiers, y compris ext4. Il n'y a pas encore d'API du noyau pour l'obtenir. Certains systèmes de fichiers tels que ntfs-3g over fuse le rendent disponible via l'API d'attribut étendu
Stéphane Chazelas le
@ StephaneChazelas Merci pour vos commentaires. Mise à jour de la réponse pour fournir plus de détails.
Thomas Nyman
Vous pouvez utiliser stappour créer votre propre API de noyau. Voir l'exemple en réponse ici.
rickhg12hs
26

TLDR; Utilisez stap( "SystemTap" ) pour créer votre propre API de noyau. Démo de l'extraction du temps de création ext4 ci-dessous.

Vous pouvez extraire les temps de création ext4 sur les systèmes Fedora 19. Voici la mienne:

$ 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

Il est clair que les inodes sur mes partitions ext4 ont le temps de création. Voici un script shell qui détermine l'inode associé à un nom de fichier, puis augmente la statsortie avec l'heure de création en utilisant stap("systemtap").

NB: Ceci est juste une démo et extrêmement inefficace puisqu'un module de noyau est créé, chargé et déchargé à chaque exécution. Ceci est également probablement très fragile car aucune vérification d'erreur n'est effectuée. Une API de noyau appropriée serait préférable, mais ce script pourrait être rendu beaucoup plus efficace et lire les temps de création de plusieurs fichiers / inodes.

[contenu 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

Voici une démo:

$ 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
la source
4
Ok, c'est juste cool. +1 pour utiliser stap, monkey corrigeant le noyau Linux, génial.
Chris Magnuson
@ChrisMagnuson: debugfs + statpermet d'obtenir crtimesans singe patcher le noyau.
jfs
17

En ext4c'est possible; car ext4le système de fichiers stocke l'heure de création du fichier. Néanmoins, vous constaterez que la statcommande ne peut pas afficher la date, car je pense que le noyau ne possède aucune API pour cela.

Quoi qu’il en soit, l’heure de naissance du fichier est enregistrée ext4et vous pouvez le trouver, mais pas par une méthode directe, mais en utilisantdebugfs

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

débutant
la source
1
comme fonction bash:xstat filename
jfs
1
Si /dev/sdxXest monté dans /some/pathet que le fichier est /some/path/some/file, le chemin à spécifier est uniquement some/file: son chemin doit être référé non à la racine du système de fichiers, mais au point de montage. Sinon, le fichier ne sera pas trouvé.
BowPark
15

En théorie, avec GNU stat, vous pouvez utiliser stat -c '%w'ou %Wobtenir la date de création d'un fichier (ou heure de naissance).

En pratique, la plupart des systèmes de fichiers n'enregistrent pas ces informations et le noyau Linux ne fournit aucun moyen d'y accéder.

Le plus proche que vous pouvez obtenir est ctime du fichier, qui n'est pas l'heure de création, mais l'heure à laquelle les métadonnées du fichier ont été modifiées.

Linux Weekly News a publié un article intéressant à ce sujet il y a quelques années - http://lwn.net/Articles/397442/

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

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

Différence entre FreeBSDet GNU\Linuxsur stat command:

Si vous appelez statcommande, GNU\Linuxelle appelle l' -x option, mais sous FreeBSD, vous devez invoquer vous-même l' -xoption.

Voir aussi Quels systèmes de fichiers sous Linux stockent l'heure de création?

Notes: --printf est très utile en scripting....!

Golfe Persique
la source
//, J'ai essayé ceci sur une machine CEntOS 6, et tout ce que j'ai obtenu était un point d'interrogation: $ stat --printf = '% w' ~ / dump.rdb? Peut-être que mon système de fichiers ne supporte pas stat avec% w.
Nathan Basanese
Malheureusement, HFS ne prend pas en charge ctime.
PersianGulf
5

Dans OS X , vous pouvez utiliser 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
la source
2

Regarde ça:

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

BTW, cela ne fonctionne que sur ext4. Je n'ai pas encore trouvé de solution pour BtrFS ...;)

Renich
la source
1
C'est à peu près ce que la réponse du débutant dit ... n'est-ce pas?
don_crissti
whoops, vous avez raison @don_crissti
Renich