Quiero averiguar la fecha de creación de un archivo en particular, no la fecha de modificación o la fecha de acceso.
He intentado con ls -ltrh
y stat filename
.
stap
para recuperar los tiempos de creación.
Quiero averiguar la fecha de creación de un archivo en particular, no la fecha de modificación o la fecha de acceso.
He intentado con ls -ltrh
y stat filename
.
stap
para recuperar los tiempos de creación.
Respuestas:
El estándar POSIX solo define tres marcas de tiempo distintas que se almacenarán para cada archivo: la hora del último acceso a datos, la hora de la última modificación de datos y la hora en que el estado del archivo cambió por última vez.
Dicho esto, los sistemas de archivos modernos de Linux, como ext4, Btrfs y JFS, almacenan el tiempo de creación del archivo (también conocido como hora de nacimiento), pero usan diferentes nombres para el campo en cuestión ( crtime
en ext4, otime
en Btrfs y JFS). Sin embargo, actualmente Linux no proporciona una API de kernel para acceder a los tiempos de creación de archivos , incluso en los sistemas de archivos que los admiten.
Como Craig Sanders y Mohsen Pahlevanzadeh señalaron, stat
no apoyar el %w
y %W
especificadores de formato de visualización de la hora del archivo a luz (en formato legible por humanos y en segundos desde el Epoch respectivamente). Sin embargo, stat
accede al tiempo de nacimiento a través del get_stat_birthtime()
proporcionado por gnulib (in lib/stat-time.h
), que obtiene el tiempo de nacimiento de los campos st_birthtime
y st_birthtimensec
de la stat
estructura devueltos por la stat()
llamada al sistema. Mientras que, por ejemplo, los sistemas BSD (y en la extensión OS X) proporcionan st_birthtime
vía stat
, Linux no. Esta es la razón por la cual las stat -c '%w' file
salidas -
(que indican un tiempo de creación desconocido) en Linux incluso para sistemas de archivos que almacenan el tiempo de creación internamente.
Como señala Stephane Chazelas , algunos sistemas de archivos, como ntfs-3g, exponen los tiempos de creación de archivos a través de atributos de archivo extendidos.
stap
para crear su propia API de kernel. Ver ejemplo en respuesta aquí.
TLDR; Use stap
( "SystemTap" ) para crear su propia API de kernel. Demostración de la extracción del tiempo de creación ext4 a continuación.
Puede extraer los tiempos de creación de ext4 en los sistemas Fedora 19. Aquí está el mío:
$ 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
Está claro que los inodes en mis particiones ext4 tienen el tiempo de creación. Aquí hay un script de shell que determina el inodo asociado con un nombre de archivo y luego aumenta la stat
salida con el tiempo de creación usando stap
("systemtap").
NB: Esto es solo una demostración y enormemente ineficiente ya que se crea, carga y descarga un módulo de kernel para cada ejecución. Esto también es probablemente muy frágil ya que no se realiza ninguna comprobación de errores. Sería preferible una API de kernel adecuada, pero este script podría hacerse mucho más eficiente y leer los tiempos de creación de múltiples archivos / inodos.
[contenido 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
Aquí hay una demostración:
$ 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
$
debugfs + stat
permite obtener crtime
sin mono parchear el núcleo.
En ext4
esto es posible; porque ext4
el sistema de archivos almacena el tiempo de creación del archivo. Pero aún así, encontrará que el stat
comando no puede mostrar la fecha, porque creo que el núcleo no tiene ninguna API para esto.
De todos modos, el tiempo de nacimiento del archivo está almacenado ext4
y puede averiguarlo, aunque no por un método directo, sino utilizandodebugfs
sudo debugfs -R "stat / ABSOLUTE / PATH" / dev / sdxX | grep crtime
xstat filename
/dev/sdxX
está montado /some/path
y el archivo está /some/path/some/file
, la ruta a especificar es solo some/file
: su ruta debe referirse no a la raíz del sistema de archivos, sino al punto de montaje. De lo contrario, no se encontrará el archivo.
En teoría, con GNU stat podría usar stat -c '%w'
o %W
para obtener la fecha de creación de un archivo (también conocido como hora de nacimiento).
En la práctica, la mayoría de los sistemas de archivos no registran esa información y el kernel de Linux no proporciona ninguna forma de acceder a ella.
Lo más cercano que puede obtener es el ctime del archivo, que no es el tiempo de creación, es el momento en que los metadatos del archivo se modificaron por última vez.
Linux Weekly News tuvo un interesante artículo sobre esto hace unos años: http://lwn.net/Articles/397442/
stat --printf='%w' yourfile #human readable
stat --printf='%W' yourfile #seconds from Epoch , 0 if unknown
Diferencia entre FreeBSD
y GNU\Linux
sobre stat command
:
Si llama al stat
comando GNU\Linux
, invoca la -x
opción, pero en FreeBSD, usted mismo debería invocar la -x
opción.
Consulte también ¿Qué sistemas de archivos en Linux almacenan el tiempo de creación?
Notas: --printf
es muy útil en scripting
....!
En OS X puede utilizar ls -lU
, stat -f%B
, GetFileInfo -d
, o 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
Mira esto:
# the last arg is the device to scan in.
debugfs -R 'stat /home/renich/somefile' /dev/sda1
Por cierto, esto funciona solo en ext4. No he encontrado una solución para BtrFS ... todavía;)
stat(1)
.