Wie finde ich das Erstellungsdatum der Datei?

104

Ich möchte das Erstellungsdatum einer bestimmten Datei herausfinden, nicht das Änderungs- oder Zugriffsdatum.

Ich habe es mit ls -ltrhund versucht stat filename.

Özzesh
quelle
5
Linux verfolgt die Erstellungszeit nicht, da sie von POSIX nicht benötigt wird. Allerdings macht Mac OS X das mit dem HFS-Dateisystem - schauen Sie unter "Geburtszeit" rein stat(1).
200_success
2
Fedora 19 ext4-Dateisysteme legen die Erstellungszeiten für Dateien fest. Ich bin mir sicher, dass es noch viele weitere Beispiele gibt. Siehe Antwort unten, die stapzum Abrufen der Erstellungszeiten verwendet wird.
Rickhg12hs

Antworten:

88

Der POSIX-Standard definiert nur drei unterschiedliche Zeitstempel , die für jede Datei gespeichert werden sollen: den Zeitpunkt des letzten Datenzugriffs, den Zeitpunkt der letzten Datenänderung und den Zeitpunkt, zu dem sich der Dateistatus zuletzt geändert hat.

In modernen Linux-Dateisystemen wie ext4, Btrfs und JFS wird zwar die Erstellungszeit (auch als Geburtszeit bezeichnet) gespeichert , für das betreffende Feld werden jedoch andere Namen verwendet ( crtimein ext4, otimeBtrfs und JFS). Doch derzeit Linux bietet keine Kernel - API für die Dateierstellungszeiten Zugriff auch auf Dateisysteme unterstützt sie.

Als Craig Sanders und Mohsen Pahlevanzadeh darauf hingewiesen, statdie unterstützt %wund %Wzum Anzeigen der Datei Geburtszeit Formatbezeichner (in für Menschen lesbares Format und in Sekunden seit der Epoche respectively). Der statZugriff auf die Geburtszeit selbst erfolgt jedoch über die get_stat_birthtime()von gnulib (in lib/stat-time.h) bereitgestellte Funktion , die die Geburtszeit aus den vom Systemaufruf zurückgegebenen Feldern st_birthtimeund st_birthtimensecder statStruktur abruft stat(). Während zum Beispiel BSD-Systeme (und in der Erweiterung OS X) st_birthtimeüber bieten stat, tut Linux dies nicht. Aus diesem Grund werden unter Linux auch stat -c '%w' fileAusgaben -(die eine unbekannte Erstellungszeit angeben) für Dateisysteme ausgegeben, in denen die Erstellungszeit intern gespeichert ist.

Wie Stephane Chazelas betont, offenbaren einige Dateisysteme, wie z. B. ntfs-3g, die Erstellungszeiten der Dateien über erweiterte Dateiattribute.

Thomas Nyman
quelle
4
Unter Linux ist es jetzt in vielen Dateisystemen gespeichert, einschließlich ext4. Es gibt jedoch noch keine Kernel-API, um diese zu erhalten. Einige Dateisysteme wie ntfs-3g over fuse stellen es über das erweiterte Attribut API
Stéphane Chazelas
@StephaneChazelas Vielen Dank für Ihre Kommentare. Die Antwort wurde aktualisiert, um weitere Details bereitzustellen.
Thomas Nyman
Sie können stapdamit Ihre eigene Kernel-API erstellen. Siehe Beispiel in Antwort hier.
Rickhg12hs
26

TLDR; Verwenden Sie stap( "SystemTap" ), um Ihre eigene Kernel-API zu erstellen. Demo der Extraktion der Erstellungszeit für ext4 weiter unten.

Sie können die ext4-Erstellungszeiten auf Fedora 19-Systemen extrahieren. Hier ist meins:

$ 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

Es ist klar, dass die Inodes auf meinen ext4-Partitionen die Erstellungszeit haben. Hier ist ein Shell-Skript, das den mit einem Dateinamen verknüpften Inode ermittelt und dann die statAusgabe mit Hilfe von stap("systemtap") um die Erstellungszeit erweitert .

NB: Dies ist nur eine Demo und äußerst ineffizient, da ein Kernelmodul für jede Ausführung erstellt, geladen und entladen wird. Dies ist wahrscheinlich auch sehr fragil, da keine Fehlerprüfung durchgeführt wird. Eine ordnungsgemäße Kernel-API wäre vorzuziehen, aber dieses Skript könnte wesentlich effizienter gestaltet werden und die Erstellungszeiten mehrerer Dateien / Inodes lesen.

[Inhalt von 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

Hier ist eine Demo:

$ 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
quelle
4
Ok, das ist einfach cool. +1 für die Verwendung von Stap, Affe Patchen des Linux-Kernels, genial.
Chris Magnuson
@ChrisMagnuson: Erlaube debugfs + states, crtimeohne Affe den Kernel zu patchen.
JFS
17

Darin ist ext4es möglich; weil ext4das Dateisystem die Erstellungszeit der Datei speichert. Trotzdem werden Sie feststellen, dass der statBefehl das Datum nicht anzeigen kann, da der Kernel meines Erachtens keine APIs dafür hat.

Wie auch immer, die Geburtszeit der Datei wird in gespeichert ext4und Sie können es herausfinden, obwohl nicht durch eine direkte Methode, sondern durch Verwendung vondebugfs

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

Anfänger
quelle
1
als bash-funktion:xstat filename
jfs
1
Wenn /dev/sdxXeingehängt ist /some/pathund die Datei ist /some/path/some/file, muss nur der Pfad angegeben werden some/file: Der Pfad muss sich nicht auf den Dateisystemstamm, sondern auf den Einhängepunkt beziehen. Andernfalls wird die Datei nicht gefunden.
BowPark
15

Theoretisch könnten Sie mit GNU stat das Erstellungsdatum einer Datei (auch bekannt als Geburtszeit) verwenden stat -c '%w'oder %Wabrufen.

In der Praxis zeichnen die meisten Dateisysteme diese Informationen nicht auf und der Linux-Kernel bietet keine Möglichkeit, darauf zuzugreifen.

Der nächstmögliche Wert ist die C-Zeit der Datei. Dies ist nicht die Erstellungszeit, sondern die Zeit, zu der die Metadaten der Datei zuletzt geändert wurden.

Linux Weekly News hatte vor ein paar Jahren einen interessanten Artikel darüber - http://lwn.net/Articles/397442/

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

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

Unterschied zwischen FreeBSDund GNU\Linuxan stat command:

Wenn Sie rufen statin Befehl GNU\Linuxruft sie die -x Option, aber in FreeBSD, Sie selbst sollten die aufrufen -xOption.

Siehe auch Welche Dateisysteme unter Linux speichern die Erstellungszeit?

Anmerkungen: --printf ist sehr nützlich in scripting....!

Persischer Golf
quelle
//, Versuchte dies auf einem CEntOS 6-Computer und alles, was ich bekam, waren Fragezeichen: $ stat --printf = '% w' ~ / dump.rdb? Möglicherweise unterstützt mein Dateisystem stat mit% w nicht.
Nathan Basanese
Leider unterstützt HFS ctime nicht.
PersianGulf
5

In OS X können Sie verwenden ls -lU, stat -f%B, GetFileInfo -d, oder 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
quelle
2

Überprüfen Sie dies heraus:

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

Übrigens funktioniert das nur mit ext4. Ich habe noch keine Lösung für BtrFS gefunden ...

Renich
quelle
1
Das ist so ziemlich die Antwort des Anfängers ... nicht wahr ?
don_crissti
whoops, du hast recht @don_crissti
Renich