Jak znaleźć datę utworzenia pliku?

104

Chcę znaleźć datę utworzenia określonego pliku, a nie datę modyfikacji lub datę dostępu.

Próbowałem z ls -ltrhi stat filename.

Özzesh
źródło
5
Linux nie śledzi czasu tworzenia, ponieważ nie jest wymagany przez POSIX. Jednak Mac OS X współpracuje z systemem plików HFS - patrz „czas urodzenia” w stat(1).
200_success
2
Systemy plików ext4 Fedory 19 ustawiają czasy tworzenia plików. Jestem pewien, że jest o wiele więcej przykładów. Zobacz odpowiedź poniżej, która służy stapdo pobierania czasów tworzenia.
rickhg12hs

Odpowiedzi:

88

Standard POSIX definiuje tylko trzy różne znaczniki czasu, które mają być przechowywane dla każdego pliku: czas ostatniego dostępu do danych, czas ostatniej modyfikacji danych oraz czas ostatniej zmiany statusu pliku.

To powiedziawszy, nowoczesne systemy plików Linux, takie jak ext4, Btrfs i JFS, przechowują czas tworzenia pliku (inaczej czas narodzin), ale używają różnych nazw dla danego pola ( crtimew ext4, otimew Btrfs i JFS). Jednak obecnie Linux nie zapewnia interfejsu API jądra umożliwiającego dostęp do czasów tworzenia plików , nawet w systemach plików, które je obsługują.

Jak zauważyli Craig Sanders i Mohsen Pahlevanzadeh , statobsługuje specyfikatory %wi %Wformat wyświetlania czasu narodzin pliku (odpowiednio w formacie czytelnym dla człowieka i w sekundach od Epoki). Jednak statsam uzyskuje dostęp do czasu narodzin za pośrednictwem get_stat_birthtime()dostarczonego przez gnulib (in lib/stat-time.h), który pobiera czas narodzin z pól st_birthtimei struktury zwróconych przez wywołanie systemowe. Chociaż na przykład systemy BSD (i w rozszerzeniu OS X) zapewniają za pośrednictwem , Linux nie. Dlatego dane wyjściowe (wskazujące nieznany czas utworzenia) w systemie Linux nawet dla systemów plików, które przechowują czas tworzenia wewnętrznie.st_birthtimensecstatstat()st_birthtimestatstat -c '%w' file-

Jak wskazuje Stephane Chazelas , niektóre systemy plików, takie jak ntfs-3g, ujawniają czasy tworzenia plików poprzez rozszerzone atrybuty plików.

Thomas Nyman
źródło
4
W systemie Linux jest teraz przechowywany w wielu systemach plików, w tym ext4. Jednak nie ma jeszcze interfejsu API jądra. Niektóre systemy plików, takie jak NTFS-3G nad bezpiecznikiem, udostępniają go za pośrednictwem rozszerzonego atrybutu API
Stéphane Chazelas
@StephaneChazelas Dziękujemy za komentarze. Zaktualizowałem odpowiedź, aby podać więcej szczegółów.
Thomas Nyman
Możesz użyć stapdo stworzenia własnego API jądra. Zobacz przykład w odpowiedzi tutaj.
rickhg12hs
26

TLDR; Użyj stap( „SystemTap” ), aby utworzyć własny interfejs API jądra. Demonstracja ekstrakcji czasu utworzenia ext4 poniżej.

Możesz wyodrębnić czasy tworzenia ext4 w systemach Fedora 19. To moje:

$ 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

Oczywiste jest, że i-węzły na moich partycjach ext4 mają czas utworzenia. Oto skrypt powłoki, który określa i-węzeł powiązany z nazwą pliku, a następnie zwiększa statwynik z czasem utworzenia za pomocą stap(„systemtap”).

Uwaga: To tylko wersja demonstracyjna i bardzo nieefektywna, ponieważ moduł jądra jest tworzony, ładowany i rozładowywany dla każdego wykonania. Jest to prawdopodobnie bardzo delikatne, ponieważ nie jest wykonywane sprawdzanie błędów. Właściwy interfejs API jądra byłby preferowany, ale ten skrypt może być znacznie bardziej wydajny i czytać czasy tworzenia wielu plików / i-węzłów.

[zawartość pliku 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

Oto 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
źródło
4
Ok, to jest po prostu fajne. +1 za użycie stap, małpa łatająca jądro Linux, super.
Chris Magnuson
@ChrisMagnuson: debugfs + statpozwala dostać się crtimebez małpki łatającej jądro.
jfs
17

W ext4to jest możliwe; ponieważ ext4system plików przechowuje czas utworzenia pliku. Ale nadal okaże się, że statpolecenie nie może wyświetlić daty, ponieważ myślę, że jądro nie ma żadnych interfejsów API do tego.

W każdym razie czas narodzin pliku jest przechowywany ext4i możesz go znaleźć, chociaż nie metodą bezpośrednią, ale za pomocądebugfs

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

początkujący
źródło
1
jako funkcja bash:xstat filename
jfs
1
Jeśli /dev/sdxXjest zamontowany, /some/patha plik jest /some/path/some/file, ścieżka, którą należy podać, to tylko some/file: jej ścieżka musi być odsyłana nie do katalogu głównego systemu plików, ale do punktu montowania. W przeciwnym razie plik nie zostanie znaleziony.
BowPark
15

Teoretycznie za pomocą GNU stat można użyć stat -c '%w'lub %Wuzyskać datę utworzenia pliku (czyli porę urodzin).

W praktyce większość systemów plików nie rejestruje tych informacji, a jądro Linuksa nie zapewnia żadnego dostępu do nich.

Najbliższy możliwy czas to czas pliku, który nie jest czasem utworzenia, jest to czas ostatniej zmiany metadanych pliku.

Linux Weekly News miał kilka ciekawych artykułów kilka lat temu - http://lwn.net/Articles/397442/

cas
źródło
7
stat --printf='%w' yourfile   #human readable

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

Różnica między FreeBSDi GNU\Linuxna stat command:

Jeśli wywołujesz statw GNU\Linuxnim polecenie , wywołuje -x opcję, ale we FreeBSD powinieneś sam ją wywołać -x.

Zobacz także Jakie systemy plików w systemie Linux przechowują czas utworzenia?

Uwagi: --printf jest bardzo przydatny w scripting...!

Zatoka Perska
źródło
//, Próbowałem tego na maszynie CEntOS 6, a dostałem tylko znaki zapytania: $ stat --printf = '% w' ~ / dump.rdb? Być może mój system plików nie obsługuje statystyki z% w.
Nathan Basanese
niestety, HFS nie obsługuje ctime.
PersianGulf
5

W OS X można użyć ls -lU, stat -f%B, GetFileInfo -dlub 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
źródło
2

Spójrz na to:

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

BTW, działa to tylko na ext4. Nie znalazłem rozwiązania dla BtrFS ... jeszcze;)

Renich
źródło
1
Tak właściwie mówi odpowiedź początkującego ... prawda?
don_crissti
Ups, masz rację @don_crissti
Renich