Як знайти дату створення файлу?


104

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

Я спробував з ls -ltrhі stat filename.


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 API для його отримання. Деякі файлові системи, такі як ntfs-3g за допомогою запобіжника, роблять його доступним через розширений API атрибутів
Stéphane Chazelas

@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 мають час створення. Ось скрипт оболонки, який визначає inode, пов’язаний з іменем файлу, а потім збільшує statвисновок із часом створення за допомогою stap("systemtap").

NB: Це просто демонстрація і надзвичайно неефективна, оскільки модуль ядра створюється, завантажується та вивантажується для кожного виконання. Це також, ймовірно, дуже крихке, оскільки перевірка помилок не проводиться. Правильний API ядра був би кращим, але цей скрипт можна зробити набагато ефективнішим і прочитати час створення декількох файлів / вкладок.

[вміст 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
$ 

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


1
як функція bash:xstat filename
jfs

1
Якщо /dev/sdxXвін встановлений, /some/pathа файл є /some/path/some/file, шлях, який слід вказати, є лише some/file: його шлях повинен бути спрямований не до кореня файлової системи, а до точки монтажу. Інакше файл не знайдеться.
BowPark

15

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

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

Найближчим ви можете отримати ctime файлу, який не час створення, це час останнього зміни метаданих файлу.

Про щотижневі новини Linux було цікава стаття про це кілька років тому - 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.
PersianGulf

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

2

Перевір це:

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

До речі, це працює лише на ext4. Я не знайшов рішення для BtrFS ... ще;)


1
Це досить багато , що beginer «s відповідь каже , що ... чи не так?
don_crissti

ой, ти прав @don_crissti
Реніч
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.