Как найти дату создания файла?

104

Я хочу узнать дату создания конкретного файла, а не дату изменения или дату доступа.

Я пытался с ls -ltrhи stat filename.

Özzesh
источник
5
Linux не отслеживает время создания, так как оно не требуется POSIX. Тем не менее, Mac OS X работает с файловой системой HFS - смотрите «время рождения» в stat(1).
200_успех
2
Файловые системы Fedora 19 ext4 устанавливают время создания файла. Я уверен, что есть еще много примеров. Смотрите ответ ниже, который используется stapдля получения времени создания.
rickhg12hs

Ответы:

88

Стандарт 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, предоставляют время создания файла через расширенные атрибуты файла.

Томас Найман
источник
4
В Linux он теперь хранится во многих файловых системах, включая ext4. Пока нет API ядра, чтобы получить его. Некоторые файловые системы, такие как ntfs-3g over fuse, делают его доступным через API расширенного атрибута
Стефан Шазелас,
@StephaneChazelas Спасибо за ваши комментарии. Обновлен ответ, чтобы предоставить больше деталей.
Томас Найман
Вы можете использовать stapдля создания своего собственного API ядра. Смотрите пример в ответе здесь.
rickhg12hs
26

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
$ 
rickhg12hs
источник
4
Хорошо, это просто круто. +1 за использование stap, обезьяна исправляет ядро ​​linux, круто.
Крис Магнусон
@ChrisMagnuson: debugfs + statпозволяет получить crtimeбез обезьян патч ядра.
Jfs
17

В ext4это возможно; потому что ext4файловая система хранит время создания файла. Но, тем не менее, вы обнаружите, что statкоманда не может показать дату, потому что я думаю, что у ядра нет API для этого.

Во всяком случае, время рождения файла хранится в, ext4и вы можете узнать его, хотя и не прямым методом, а с помощьюdebugfs

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

beginer
источник
1
как функция bash:xstat filename
JFS
1
Если файл /dev/sdxXподключен, /some/pathа файл есть /some/path/some/file, указывается только some/fileпуть: его путь должен указывать не на корень файловой системы, а на точку монтирования. В противном случае файл не будет найден.
BowPark
15

Теоретически, с помощью GNU stat вы можете использовать stat -c '%w'или %Wполучить дату создания файла (то есть время рождения).

На практике большинство файловых систем не записывают эту информацию, а ядро ​​Linux не предоставляет никакого способа доступа к ней.

Самое близкое, что вы можете получить - это ctime файла, это не время создания, а время последнего изменения метаданных файла.

У Linux Weekly News была интересная статья об этом несколько лет назад - http://lwn.net/Articles/397442/

саз
источник
7
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....!

Персидский залив
источник
//, пробовал это на машине CEntOS 6, и все, что я получил, было вопросительными знаками: $ stat --printf = '% w' ~ / dump.rdb? Может быть, моя файловая система не поддерживает stat с% w.
Натан Басанезе
К сожалению, HFS не поддерживает ctime.
Персидский залив
5

В 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
LRI
источник
2

Проверь это:

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

Кстати, это работает только на ext4. Я не нашел решения для BtrFS ... пока;)

Renich
источник
1
Это почти то, что говорит ответ новичка ... не так ли?
don_crissti
Ой, ты прав @don_crissti
Рених