Я хочу узнать дату создания конкретного файла, а не дату изменения или дату доступа.
Я пытался с ls -ltrh
и stat filename
.
stap
для получения времени создания.
Я хочу узнать дату создания конкретного файла, а не дату изменения или дату доступа.
Я пытался с ls -ltrh
и stat filename
.
stap
для получения времени создания.
Ответы:
Стандарт POSIX определяет только три различные временные метки, которые должны храниться для каждого файла: время последнего доступа к данным, время последней модификации данных и время последнего изменения статуса файла.
Тем не менее, современные файловые системы Linux, такие как ext4, Btrfs и JFS, хранят время создания файла (или время рождения), но используют разные имена для рассматриваемого поля ( crtime
в ext4, otime
в Btrfs и JFS). Однако в настоящее время Linux не предоставляет API ядра для доступа ко времени создания файлов , даже в файловых системах, поддерживающих их.
Как указали Крейг Сандерс и Мохсен Палеванзаде , stat
он поддерживает спецификаторы формата %w
и %W
для отображения времени рождения файла (в удобочитаемом формате и в секундах с начала эпохи соответственно). Однако, stat
сам по себе доступ к времени рождения с помощью get_stat_birthtime()
обеспечивается gnulib (в lib/stat-time.h
), которая получает время от рождения st_birthtime
и st_birthtimensec
полой stat
структуры , возвращенной stat()
системного вызовом. В то время как, например, системы BSD (и в расширении OS X) предоставляют st_birthtime
через stat
, Linux не делает. Вот почему stat -c '%w' file
вывод -
(с указанием неизвестного времени создания) в Linux даже для файловых систем, которые хранят время создания внутри.
Как указывает Стефан Чазелас , некоторые файловые системы, такие как ntfs-3g, предоставляют время создания файла через расширенные атрибуты файла.
stap
для создания своего собственного API ядра. Смотрите пример в ответе здесь.
TLDR; Используйте stap
( «SystemTap» ) для создания собственного API ядра. Демонстрация извлечения времени создания ext4 ниже.
Вы можете извлечь время создания ext4 в системах Fedora 19. Вот мой:
$ 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
Понятно, что иноды на моих разделах ext4 имеют время создания. Вот сценарий оболочки, который определяет индекс, связанный с именем файла, а затем дополняет stat
вывод временем создания, используя stap
("systemtap").
NB: Это просто демонстрация и крайне неэффективная, поскольку модуль ядра создается, загружается и выгружается для каждого выполнения. Это также, вероятно, очень хрупко, поскольку проверка ошибок не выполняется. Правильный API ядра был бы предпочтительнее, но этот сценарий можно было бы сделать намного более эффективным и считывать время создания нескольких файлов / inode.
[содержимое 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
Вот демо:
$ 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
позволяет получить crtime
без обезьян патч ядра.
В ext4
это возможно; потому что ext4
файловая система хранит время создания файла. Но, тем не менее, вы обнаружите, что stat
команда не может показать дату, потому что я думаю, что у ядра нет API для этого.
Во всяком случае, время рождения файла хранится в, ext4
и вы можете узнать его, хотя и не прямым методом, а с помощьюdebugfs
sudo debugfs -R "stat / ABSOLUTE / PATH" / dev / sdxX | grep crtime
xstat filename
/dev/sdxX
подключен, /some/path
а файл есть /some/path/some/file
, указывается только some/file
путь: его путь должен указывать не на корень файловой системы, а на точку монтирования. В противном случае файл не будет найден.
Теоретически, с помощью GNU stat вы можете использовать stat -c '%w'
или %W
получить дату создания файла (то есть время рождения).
На практике большинство файловых систем не записывают эту информацию, а ядро Linux не предоставляет никакого способа доступа к ней.
Самое близкое, что вы можете получить - это ctime файла, это не время создания, а время последнего изменения метаданных файла.
У Linux Weekly News была интересная статья об этом несколько лет назад - http://lwn.net/Articles/397442/
stat --printf='%w' yourfile #human readable
stat --printf='%W' yourfile #seconds from Epoch , 0 if unknown
Разница между FreeBSD
и GNU\Linux
на stat command
:
Если вы вызываете stat
команду, в GNU\Linux
ней вызывается -x
опция, но во FreeBSD вы сами должны вызывать эту -x
опцию.
Смотрите также Какие файловые системы в Linux хранят время создания?
Примечания: --printf
очень полезно в scripting
....!
В OS X вы можете использовать ls -lU
, stat -f%B
, GetFileInfo -d
или 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
Проверь это:
# the last arg is the device to scan in.
debugfs -R 'stat /home/renich/somefile' /dev/sda1
Кстати, это работает только на ext4. Я не нашел решения для BtrFS ... пока;)
stat(1)
.