ฉันต้องการค้นหาเวลาในการสร้างไฟล์เมื่อฉันอ่านบทความเกี่ยวกับปัญหานี้ทุกคนกล่าวถึงว่าไม่มีวิธีแก้ปัญหา (เช่นไซต์ 1 , ไซต์ 2 )
เมื่อฉันพยายามคำสั่งมันฯstat
Birth: -
ดังนั้นฉันจะหาเวลาสร้างไฟล์ได้อย่างไร
ฉันต้องการค้นหาเวลาในการสร้างไฟล์เมื่อฉันอ่านบทความเกี่ยวกับปัญหานี้ทุกคนกล่าวถึงว่าไม่มีวิธีแก้ปัญหา (เช่นไซต์ 1 , ไซต์ 2 )
เมื่อฉันพยายามคำสั่งมันฯstat
Birth: -
ดังนั้นฉันจะหาเวลาสร้างไฟล์ได้อย่างไร
คำตอบ:
มีวิธีรู้วันที่สร้างของไดเรกทอรีเพียงทำตามขั้นตอนเหล่านี้:
รู้จักinodeของไดเร็กตอรี่โดย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 คือวันที่สร้างไฟล์ของคุณ
สิ่งที่ฉันทดสอบ :
แก้ไขโดยการสร้างไฟล์
ฉันลองใช้คำสั่งและให้เวลาที่แน่นอน
debugfs
แยกมันโดยตรงจากระบบไฟล์จึงไม่จำเป็นต้องใช้ API ของเคอร์เนล ดูที่นี่
statx()
ณ เดือนมีนาคม 2019
@Nux พบทางออกที่ดีสำหรับสิ่งนี้ซึ่งคุณควร upvote ทั้งหมด ฉันตัดสินใจที่จะเขียนฟังก์ชั่นเล็ก ๆ น้อย ๆ ที่สามารถใช้เพื่อเรียกใช้ทุกอย่างโดยตรง ~/.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 จะให้ wrapper ที่ทำให้งานง่ายขึ้น แต่ glibc จะเพิ่ม wrapper สำหรับ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
คำสั่งเก่าแบบธรรมดาสำหรับสิ่งนี้ แต่ฉันไม่คิดว่านี่จะ backported เพื่อ LTS รุ่นแม้ว่าพวกเขาจะได้รับเมล็ดใหม่ ดังนั้นฉันไม่ได้คาดหวังstat
กับการเปิดตัว LTS ใด ๆ ในปัจจุบัน (14.04, 16.04 หรือ 18.04) เพื่อพิมพ์เวลาการสร้างโดยไม่ต้องมีการแทรกแซงด้วยตนเอง
อย่างไรก็ตามในวันที่ 18.10 คุณสามารถใช้งานstatx
ฟังก์ชั่นได้โดยตรงตามที่อธิบายไว้ในman 2 statx
(หมายเหตุว่า 18.10 manpage นั้นไม่ถูกต้องในการระบุว่า glibc ยังไม่ได้เพิ่ม wrapper)
1
?
TL; DR:
เพิ่งรัน:
sudo debugfs -R 'stat /path/to/your/file' /dev/<your fs>
(หากต้องการหาค่า 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
ในการส่งออกให้มองหา