Мені потрібно знайти час створення файлу, коли я читав деякі статті про цю проблему, всі згадували, що рішення немає (наприклад, Site1 , Site2 ).
Коли я спробував stat
команду, він констатує Birth: -
.
Тож як я можу знайти час створення файлу?
Мені потрібно знайти час створення файлу, коли я читав деякі статті про цю проблему, всі згадували, що рішення немає (наприклад, Site1 , Site2 ).
Коли я спробував stat
команду, він констатує Birth: -
.
Тож як я можу знайти час створення файлу?
Відповіді:
Існує спосіб дізнатися дату створення каталогу, просто виконайте наступні дії:
Знайти вкладення каталогу за ls -i
командою (скажімо, наприклад, його X )
Знайте, на якому розділі ваша df -T /path
команда зберігається за допомогою команди (давайте скажемо її на /dev/sda1
)
Тепер використовуйте цю команду: sudo debugfs -R 'stat <X>' /dev/sda1
Ви побачите у висновку:
crtime: 0x4e81cacc:966104fc -- mon Sep 27 14:38:28 2013
crtime - дата створення вашого файлу.
Що я тестував :
Змінив його, створивши файл.
Я спробував команду, і це дало точний час.
statx()
станом на березень 2019 року.
@Nux знайшов для цього чудове рішення, яке ви повинні підтримати. Я вирішив написати невелику функцію, яку можна використовувати для запуску всього безпосередньо. Просто додайте це до свого
~/.bashrc
.
get_crtime() {
for target in "${@}"; do
inode=$(stat -c '%i' "${target}")
fs=$(df --output=source "${target}" | tail -1)
crtime=$(sudo debugfs -R 'stat <'"${inode}"'>' "${fs}" 2>/dev/null |
grep -oP 'crtime.*--\s*\K.*')
printf "%s\t%s\n" "${target}" "${crtime}"
done
}
Тепер ви можете запустити get_crtime
для друку дат створення стільки файлів чи каталогів, скільки вам подобається:
$ get_crtime foo foo/file
foo Wed May 21 17:11:08 2014
foo/file Wed May 21 17:11:27 2014
cp -p
або подібного.
df
не підтримує цю --output
опцію. У цьому випадку ви можете замінити цей рядок fs=$(df foo | awk '{a=$1}END{print a}'
і функція також буде працювати. Все, що я показую в цій відповіді, - це спосіб вивести команду з прийнятої відповіді таким чином, який можна запустити безпосередньо для цілей файлів / каталогів.
Неможливість stat
відображення часу створення створюється через обмеження stat(2)
системного виклику , структура повернення якого не містила поля для часу створення. Починаючи з Linux 4.11 (тобто, 17.10 і новішого *), однак, новий statx(2)
системний виклик доступний, що включає в себе час створення у його структурі повернення.
* І, можливо, на старих випусках LTS з використанням ядер програмного забезпечення стеку (HWE). Перевірте, uname -r
чи використовуєте ядро принаймні на 4.11 для підтвердження.
На жаль, зателефонувати в системні дзвінки безпосередньо через програму C непросто. Зазвичай glibc забезпечує обгортку, яка робить роботу легкою, але glibc обгортку додав лише statx(2)
у серпні 2018 року (версія 2.28 , доступна в 18.10). На щастя, @whotwagner написав зразок програми C, який показує, як використовувати statx(2)
системний виклик для систем x86 та x86-64. Його вихід має той самий формат, що stat
і за замовчуванням, без будь-яких варіантів форматування, але його легко змінити, щоб надрукувати лише час народження.
По-перше, клонуйте його:
git clone https://github.com/whotwagner/statx-fun
Ви можете скласти statx.c
код або, якщо ви просто хочете час народження, створити birth.c
в каталозі клонований наступний код (який є мінімальною версією statx.c
друку просто часової позначки створення, включаючи наносекундну точність):
#define _GNU_SOURCE
#define _ATFILE_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>
#include <fcntl.h>
#include "statx.h"
#include <time.h>
#include <getopt.h>
#include <string.h>
// does not (yet) provide a wrapper for the statx() system call
#include <sys/syscall.h>
/* this code works ony with x86 and x86_64 */
#if __x86_64__
#define __NR_statx 332
#else
#define __NR_statx 383
#endif
#define statx(a,b,c,d,e) syscall(__NR_statx,(a),(b),(c),(d),(e))
int main(int argc, char *argv[])
{
int dirfd = AT_FDCWD;
int flags = AT_SYMLINK_NOFOLLOW;
unsigned int mask = STATX_ALL;
struct statx stxbuf;
long ret = 0;
int opt = 0;
while(( opt = getopt(argc, argv, "alfd")) != -1)
{
switch(opt) {
case 'a':
flags |= AT_NO_AUTOMOUNT;
break;
case 'l':
flags &= ~AT_SYMLINK_NOFOLLOW;
break;
case 'f':
flags &= ~AT_STATX_SYNC_TYPE;
flags |= AT_STATX_FORCE_SYNC;
break;
case 'd':
flags &= ~AT_STATX_SYNC_TYPE;
flags |= AT_STATX_DONT_SYNC;
break;
default:
exit(EXIT_SUCCESS);
break;
}
}
if (optind >= argc) {
exit(EXIT_FAILURE);
}
for (; optind < argc; optind++) {
memset(&stxbuf, 0xbf, sizeof(stxbuf));
ret = statx(dirfd, argv[optind], flags, mask, &stxbuf);
if( ret < 0)
{
perror("statx");
return EXIT_FAILURE;
}
printf("%lld.%u\n", *&stxbuf.stx_btime.tv_sec, *&stxbuf.stx_btime.tv_nsec);
}
return EXIT_SUCCESS;
}
Тоді:
$ make birth
$ ./birth ./birth.c
1511793291.254337149
$ ./birth ./birth.c | xargs -I {} date -d @{}
Mon Nov 27 14:34:51 UTC 2017
Теоретично це повинно зробити час створення більш доступним:
debugfs
це інструмент для файлових систем ext2 / 3/4 і непридатний для інших)make
і linux-libc-dev
).Тестування системи xfs, наприклад:
$ truncate -s 1G temp; mkfs -t xfs temp; mkdir foo; sudo mount temp foo; sudo chown $USER foo
$ touch foo/bar
$ # some time later
$ echo > foo/bar
$ chmod og-w foo/bar
$ ./birth foo/bar | xargs -I {} date -d @{}
Mon Nov 27 14:43:21 UTC 2017
$ stat foo/bar
File: foo/bar
Size: 1 Blocks: 8 IO Block: 4096 regular file
Device: 700h/1792d Inode: 99 Links: 1
Access: (0644/-rw-r--r--) Uid: ( 1000/ muru) Gid: ( 1000/ muru)
Access: 2017-11-27 14:43:32.845579010 +0000
Modify: 2017-11-27 14:44:38.809696644 +0000
Change: 2017-11-27 14:44:45.536112317 +0000
Birth: -
Однак це не спрацювало для NTFS та exfat. Я думаю, що файлові системи FUSE для них не включали час створення.
Якщо, а точніше, коли, glibc додасть підтримку для statx(2)
системного виклику, stat
незабаром відбудеться, і ми зможемо використовувати для цього звичайну стару stat
команду. Але я не думаю, що це буде підтримуватися до випусків LTS, навіть якщо вони отримають новіші ядра. Отже, я не очікую, що stat
в будь-якому поточному випуску LTS (14.04, 16.04 або 18.04) коли-небудь надрукувати час створення без ручного втручання.
Однак 18.10 ви можете безпосередньо використовувати statx
функцію, як описано в man 2 statx
(зауважте, що сторінка 18.10 невірна, заявивши, що glibc ще не додав обгортку).
1
?
TL; DR:
Просто запустіть:
sudo debugfs -R 'stat /path/to/your/file' /dev/<your fs>
(Щоб розібратися у вашому фс, біжіть df -T /path/to/your/file
, швидше за все, це буде /dev/sda1
).
Довга версія:
Ми будемо виконувати дві команди:
Дізнайтеся назву імені розділу для вашого файлу.
df -T /path/to/your/file
Вихід буде виглядати приблизно так (ім'я розділу спочатку):
Filesystem Type 1K-blocks Used Available Use% Mounted on
/dev/<your fs> ext4 7251432 3481272 3509836 50% /
Дізнайтеся час створення цього файлу.
sudo debugfs -R 'stat /path/to/your/file' /dev/<your fs>
У виході шукайте ctime
.