Chcę znaleźć datę utworzenia określonego pliku, a nie datę modyfikacji lub datę dostępu.
Próbowałem z ls -ltrh
i stat filename
.
stap
do pobierania czasów tworzenia.
Chcę znaleźć datę utworzenia określonego pliku, a nie datę modyfikacji lub datę dostępu.
Próbowałem z ls -ltrh
i stat filename
.
stap
do pobierania czasów tworzenia.
Odpowiedzi:
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 ( crtime
w ext4, otime
w 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 , stat
obsługuje specyfikatory %w
i %W
format wyświetlania czasu narodzin pliku (odpowiednio w formacie czytelnym dla człowieka i w sekundach od Epoki). Jednak stat
sam 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_birthtime
i 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_birthtimensec
stat
stat()
st_birthtime
stat
stat -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.
stap
do stworzenia własnego API jądra. Zobacz przykład w odpowiedzi tutaj.
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 stat
wynik 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
$
debugfs + stat
pozwala dostać się crtime
bez małpki łatającej jądro.
W ext4
to jest możliwe; ponieważ ext4
system plików przechowuje czas utworzenia pliku. Ale nadal okaże się, że stat
polecenie 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 ext4
i możesz go znaleźć, chociaż nie metodą bezpośrednią, ale za pomocądebugfs
sudo debugfs -R "stat / ABSOLUTE / PATH" / dev / sdxX | grep crtime
xstat filename
/dev/sdxX
jest zamontowany, /some/path
a 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.
Teoretycznie za pomocą GNU stat można użyć stat -c '%w'
lub %W
uzyskać 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/
stat --printf='%w' yourfile #human readable
stat --printf='%W' yourfile #seconds from Epoch , 0 if unknown
Różnica między FreeBSD
i GNU\Linux
na stat command
:
Jeśli wywołujesz stat
w GNU\Linux
nim 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
...!
W OS X można użyć ls -lU
, stat -f%B
, GetFileInfo -d
lub 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
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;)
stat(1)
.