Je veux connaître la date de création d'un fichier particulier, pas la date de modification ou la date d'accès.
J'ai essayé avec ls -ltrh
et stat filename
.
stat -c '%w' file
Sur les systèmes de fichiers qui stockent l'heure de création.
Notez que sous Linux, cela nécessite coreutils
8.31, glibc
2.28 et la version du noyau 4.11 ou plus récente .
La norme POSIX définit uniquement 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 de l'état du fichier.
Les systèmes de fichiers Linux modernes, tels que ext4, Btrfs et JFS, stockent l'heure de création du fichier (alias heure de naissance), mais utilisent des noms différents pour le champ en question (crtime
dans ext4, otime
en Btrfs et JFS). Linux fournit l'interface d'appel système statx (2) pour récupérer l'heure de naissance des fichiers pour les systèmes de fichiers qui le prennent en charge depuis la version 4.11 du noyau.
Comme Craig Sanders et Mohsen Pahlevanzadeh l'ont souligné, stat
prend en charge les spécificateurs de format %w
Et %W
Pour afficher les heure de naissance du fichier (au format lisible par l'homme et en secondes depuis Epoch respectivement) avant coreutils
version 8.31. Cependant, coreutils
stat
utilise l'appel système statx()
lorsqu'il est disponible pour récupérer l'heure de naissance uniquement depuis la version 8.31. Avant coreutils
version 8.31 stat
accédait à l'heure de naissance via la get_stat_birthtime()
fournie par gnulib (dans lib/stat-time.h
), Qui obtient l'heure de naissance de la st_birthtime
Et st_birthtimensec
De la structure stat
renvoyée par l'appel système stat()
. Alors que par exemple, les systèmes BSD (et dans l'extension OS X) fournissent st_birthtime
Via stat
, Linux ne le fait pas. C'est pourquoi stat -c '%w' file
Affiche -
(Indiquant une heure de création inconnue) sur Linux avant coreutils
8.31 même pour les systèmes de fichiers qui stockent l'heure de création en interne.
Comme 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.
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 de 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 sortie stat
avec l'heure de création en utilisant stap
("systemtap").
NB: Ceci est juste une démo et extrêmement inefficace car un module du noyau est créé, chargé et déchargé pour 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
$
En théorie, avec GNU stat, vous pourriez utiliser stat -c '%w'
ou %W
pour obtenir la date de création d'un fichier (aka 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 le ctime du fichier, qui est pas l'heure de création, c'est l'heure de la dernière modification des métadonnées du fichier.
Linux Weekly News avait un article intéressant à ce sujet il y a quelques années - Temps de création de fichiers .
Dans ext4
c'est possible; parce que ext4
le système de fichiers stocke l'heure de création du fichier. Mais encore, vous constaterez que la commande stat
ne peut pas afficher la date, car je pense que le noyau n'a pas d'API pour cela.
Quoi qu'il en soit, l'heure de naissance du fichier est stockée dans ext4
et vous pouvez le découvrir, mais pas par une méthode directe, mais en utilisant debugfs
Sudo debugfs -R "stat/ABSOLUTE/PATH"/dev/sdxX | grep crtime
stat --printf='%w' yourfile #human readable
stat --printf='%W' yourfile #seconds from Epoch , 0 if unknown
Différence entre FreeBSD
et GNU\Linux
sur stat command
:
Si vous appelez la commande stat
dans GNU\Linux
il invoque le -x
, mais dans FreeBSD, vous devez invoquer vous-même -x
option.
Voir aussi Quels systèmes de fichiers sur Linux stockent l'heure de création?
Remarques: --printf
est très utile dans scripting
....!
Sous OS X, vous pouvez utiliser 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
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 ...)