Birth
방금 해당 부분을 읽어보니 stat
ext4가 지원해야 할 것 같은데, 방금 생성한 파일에도 공백이 남아있습니다.
~ % touch test slave-iv
~ % stat test.pl slave-iv
File: ‘test.pl’
Size: 173 Blocks: 8 IO Block: 4096 regular file
Device: 903h/2307d Inode: 41943086 Links: 1
Access: (0600/-rw-------) Uid: ( 1000/xenoterracide) Gid: ( 100/ users)
Access: 2012-09-22 18:22:16.924634497 -0500
Modify: 2012-09-22 18:22:16.924634497 -0500
Change: 2012-09-22 18:22:16.947967935 -0500
Birth: -
~ % sudo tune2fs -l /dev/md3 | psp4 slave-iv
tune2fs 1.42.5 (29-Jul-2012)
Filesystem volume name: home
Last mounted on: /home
Filesystem UUID: ab2e39fb-acdd-416a-9e10-b501498056de
Filesystem magic number: 0xEF53
Filesystem revision #: 1 (dynamic)
Filesystem features: has_journal ext_attr resize_inode dir_index filetype needs_recovery extent flex_bg sparse_super large_file huge_file uninit_bg dir_nlink extra_isize
Filesystem flags: signed_directory_hash
Default mount options: journal_data
Filesystem state: clean
Errors behavior: Continue
Filesystem OS type: Linux
Inode count: 59736064
Block count: 238920960
Reserved block count: 11946048
Free blocks: 34486248
Free inodes: 59610013
First block: 0
Block size: 4096
Fragment size: 4096
Reserved GDT blocks: 967
Blocks per group: 32768
Fragments per group: 32768
Inodes per group: 8192
Inode blocks per group: 512
RAID stride: 128
RAID stripe width: 256
Flex block group size: 16
Filesystem created: Mon May 31 20:36:30 2010
Last mount time: Sat Oct 6 11:01:01 2012
Last write time: Sat Oct 6 11:01:01 2012
Mount count: 14
Maximum mount count: 34
Last checked: Tue Jul 10 08:26:37 2012
Check interval: 15552000 (6 months)
Next check after: Sun Jan 6 07:26:37 2013
Lifetime writes: 7255 GB
Reserved blocks uid: 0 (user root)
Reserved blocks gid: 0 (group root)
First inode: 11
Inode size: 256
Required extra isize: 28
Desired extra isize: 28
Journal inode: 8
First orphan inode: 55313243
Default directory hash: half_md4
Directory Hash Seed: 442c66e8-8b67-4a8c-92a6-2e2d0c220044
Journal backup: inode blocks
내 파티션에 대해 이 필드가 채워지지 않는 이유는 무엇입니까 ext4
?
답변1
필드는 채워지기만 하고(아래 참조) coreutils stat
표시되지 않습니다. 분명히 그들은 기다리고 있는 것 같다 1 waitxstat()
상호 작용.
stat(1) 및 ls(1)은 출생 시간을 지원합니다. 커널에서 제공하는 xstat()에 의존합니다.
다음을 통해 생성 시간을 얻을 수 있습니다 debugfs
.
debugfs -R 'stat <inode_number>' DEVICE
예를 들어 내 중 어느 것이 /etc/profile
열려 있는지 /dev/sda2
(참조파일이 어떤 장치에 있는지 확인하는 방법):
stat -c %i /etc/profile 398264
debugfs -R 'stat <398264>' /dev/sda2
debugfs 1.42.5 (29-Jul-2012)
Inode: 398264 Type: regular Mode: 0644 Flags: 0x80000
Generation: 2058737571 Version: 0x00000000:00000001
User: 0 Group: 0 Size: 562
File ACL: 0 Directory ACL: 0
Links: 1 Blockcount: 8
Fragment: Address: 0 Number: 0 Size: 0
ctime: 0x506b860b:19fa3c34 -- Wed Oct 3 02:25:47 2012
atime: 0x50476677:dcd84978 -- Wed Sep 5 16:49:27 2012
mtime: 0x506b860b:19fa3c34 -- Wed Oct 3 02:25:47 2012
crtime: 0x50476677:dcd84978 -- Wed Sep 5 16:49:27 2012
Size of extra inode fields: 28
EXTENTS:
(0):3308774
시간 필드 의미:
ctime
: 파일 변경 시간.atime
: 파일 접근 시간.mtime
: 파일 수정 시간.crtime
: 파일 생성 시간.
1 LKML에 대한 리누스의 답변철사
답변2
나는 이것을 간단한 쉘 함수로 결합했습니다.
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 foo foo/file /etc/
foo Wed May 21 17:11:08 2014
foo/file Wed May 21 17:11:27 2014
/etc/ Wed Aug 1 20:42:03 2012
답변3
이 xstat
기능은 메인라인에 병합된 적이 없습니다. 그러나 새로운statx
나중에 전화하자고 제안했는데, 그리고리눅스 4.11에 병합. 새로운statx(2)
시스템 호출은 반환 구조에 생성 시간을 포함합니다. 래퍼는 statx(2)
glibc에만 추가되었습니다.2.28(2018년 8월 출시). 이 래퍼 사용에 대한 지원이 추가되었습니다.GNU 코어 유틸리티 8.31(2019년 3월 게시):
glibc >= 2.28 및 커널 >= 4.11을 사용하는 GNU Linux 시스템에서 stat는 이제 파일 시스템이 지원하는 경우 파일 생성 시간을 인쇄합니다.
% stat --version
stat (GNU coreutils) 8.31
Copyright (C) 2019 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <https://gnu.org/licenses/gpl.html>.
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
Written by Michael Meskes.
% stat /
File: /
Size: 4096 Blocks: 8 IO Block: 4096 directory
Device: b302h/45826d Inode: 2 Links: 17
Access: (0755/drwxr-xr-x) Uid: ( 0/ root) Gid: ( 0/ root)
Access: 2019-06-06 20:03:12.898725626 +0900
Modify: 2019-05-28 05:15:44.452651395 +0900
Change: 2019-05-28 05:15:44.452651395 +0900
Birth: 2018-06-07 20:35:54.000000000 +0900
statx
다음은 userland가 아직 따라잡지 못한 부분(이전 glibc 또는 coreutils)을 보여주는 데모입니다 . C 프로그램에서 직접 시스템 호출을 호출하는 것은 쉽지 않습니다. 일반적으로 glibc는 작업을 쉽게 만드는 래퍼를 제공하지만 운 좋게도 @whotwagner는 다음과 같이 썼습니다.C 프로그램 예statx(2)
x86 및 x86-64 시스템에서 시스템 호출을 사용하는 방법을 보여줍니다 . 출력 형식은 서식 옵션 없이 기본값과 동일 stat
하지만, 출생 시간만 인쇄하도록 쉽게 수정됩니다. (충분히 새로운 glibc를 가지고 있다면 이것이 필요하지 않을 것입니다 statx
.man 2 statx
).
먼저 복제합니다.
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
이론적으로 이는 ext* 파일 시스템보다 더 많은 파일 시스템에서 생성 시간에 액세스할 수 있도록 해야 합니다( debugfs
ext2/3/4 파일 시스템용 도구이며 다른 시스템에서는 사용할 수 없음). XFS 시스템에서는 작동하지만 NTFS 및 exfat에서는 작동하지 않습니다. 이러한 FUSE 파일 시스템에는 생성 시간이 포함되지 않는 것 같습니다.
답변4
생성 시간이 null/0/대시인 또 다른 경우가 있습니다. Ext4의 Inode 크기는 저장하려면 최소 256바이트여야 합니다 crtime
. 이 문제가 있는 경우원래 생성된512MB보다 작은 파일 시스템(기본 Inode 크기는 128바이트입니다. /etc/mke2fs.conf
및 mkfs.ext4
맨페이지 참조)
stat -c '%n: %w' testfile
testfile: -
그리고/또는
stat -c '%n: %W' testfile
testfile: 0
이제 파일 시스템 inode를 확인하십시오(저장할 수 있을 만큼 큰가요 crtime
?).
tune2fs -l $(df . --output=source | grep ^/) | grep "Inode size:"
Inode size: 128
기술 정보: 소개Ext4 디스크 레이아웃페이지에서 inode 테이블의 일부 속성이 0x80(128)을 초과한다는 점에 유의하세요.