मुझे फ़ाइल का निर्माण समय कैसे मिलेगा?


64

मुझे एक फ़ाइल का निर्माण समय खोजने की आवश्यकता है, जब मैंने इस मुद्दे के बारे में कुछ लेख पढ़े, तो सभी ने उल्लेख किया कि कोई समाधान नहीं है (जैसे साइट 1 , साइट 2 )।

जब मैंने statकमांड की कोशिश की , तो यह कहा गया Birth: -

तो मैं एक फ़ाइल का निर्माण समय कैसे पा सकता हूं?


2
ध्यान रखें कि किसी फ़ाइल का 'निर्माण समय' सटीक होने की गारंटी नहीं है। किसी फ़ाइल पर निर्माण तिथियों को 'ठगना' करने के कई तरीके हैं।
थॉमस वार्ड

1
@ThomasWard अन्य फ़ाइल डेटा को ठगने के तरीकों की तुलना में कई अधिक है?
सीस टिमरमैन

जवाबों:


67

किसी निर्देशिका की निर्माण तिथि जानने का एक तरीका है, बस इन चरणों का पालन करें:

  1. कमांड द्वारा निर्देशिका का इनकोड ज्ञात करेंls -i (उदाहरण के लिए इसके X को कहने दें )

  2. यह जान लें कि आपकी निर्देशिका को किस df -T /pathकमांड द्वारा सहेजा गया है (इसके बारे में बताएं /dev/sda1)

  3. अब इस कमांड का उपयोग करें: sudo debugfs -R 'stat <X>' /dev/sda1

आप आउटपुट में देखेंगे:

crtime: 0x4e81cacc:966104fc -- mon Sep 27 14:38:28 2013

crtime आपकी फ़ाइल की निर्माण तिथि है।

मैंने क्या परीक्षण किया :

  1. विशिष्ट समय पर एक निर्देशिका बनाई गई।
  2. इसे एक्सेस किया।
  3. एक फ़ाइल बनाकर इसे संशोधित किया।

  4. मैंने कमांड की कोशिश की और यह एक सटीक समय दिया।

  5. फिर मैं इसे संशोधित करता हूं, और फिर से परीक्षण करता हूं, क्राइम एक ही रहा, लेकिन संशोधित और एक्सेस समय बदल गया।

मैं इस पोस्ट, क्योंकि मैं चर्चा करने के लिए तो मैं बेहतर समझ सकते हैं की तरह है, मैं क्यों लोगों का कहना है कि लिनक्स इस सुविधा का समर्थन नहीं करता हूँ
nux

13
क्योंकि लिनक्स ही नहीं है। Ext4 फाइलसिस्टम में यह जानकारी है लेकिन कर्नेल इसे एक्सेस करने के लिए एक एपीआई प्रदान नहीं करता है। जाहिर है, debugfsइसे सीधे फाइलसिस्टम से निकालता है , इसलिए इसे कर्नेल के एपीआई का उपयोग करने की आवश्यकता नहीं है। देखें यहाँ
terdon

मैंने इसका परीक्षण किया। यह ext4 फाइल सिस्टम पर पूरी तरह से काम करता है
फहीम बाबर पटेल

1
ऐसा लगता है कि ext4 विशिष्ट है? यह मेरे लिए XFS के साथ काम नहीं किया।
क्वांटम 7

गिरी, glibc, और coreutils सब अब समर्थन statx()मार्च 2019 के रूप में
hippietrail

54

@ नक्स ने इसके लिए एक शानदार उपाय ढूंढा, जिसे आप सभी को पूरा करना चाहिए। मैंने एक छोटा सा फंक्शन लिखने का फैसला किया जिसका इस्तेमाल सब कुछ सीधे चलाने के लिए किया जा सके। बस इसे अपने में जोड़ें ~/.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

ध्यान दें कि निर्माण तिथि मूल फ़ाइल की निर्माण तिथि अगर फाइल एक प्रति है (जैसे कि यह नहीं है है संशोधन दिनांक के साथ)। एक बार एक फ़ाइल की नकल की जाती है, संशोधन की तारीख मूल से होती है, लेकिन निर्माण की तारीख कॉपी से होती है। (इस प्रश्न में कुछ गलतफहमी है: askubuntu.com/questions/529885/… )
जैकब व्लिजम

1
@JacobVlijm अच्छी तरह से, हाँ, बिल्कुल। यह स्पष्ट नहीं है? यह अन्यथा कैसे हो सकता है? एक प्रतिलिपि एक नई फ़ाइल है जो बस उसी सामग्री को होती है जो दूसरे के रूप में होती है। संशोधन का समय भी कॉपी के लिए बदल जाता है। जब तक आप स्पष्ट रूप से इस बात का चयन नहीं करेंगे कि आप स्पष्ट रूप से इसका उपयोग नहीं करते हैं cp -pया समान नहीं हैं।
terdon

बिल्कुल, लेकिन यह एक ही समय में, यह वैसा ही नहीं होगा अगर, मॉड की तरह। तारीख, फ़ाइल में कहीं तारीख की उत्पत्ति होने पर संग्रहीत की जाएगी। मुझे मानना ​​चाहिए कि मुझे नहीं पता था कि जब तक मैं जुड़ा हुआ सवाल का जवाब नहीं देता, तब तक ऐसा नहीं था।
जैकब व्लिजम

जिस तरह से मैंने कोशिश की, मैंने सिर्फ फाइल को नॉटिलस में कॉपी किया, संशोधन की तारीख जैसे ही (थी), मी। निर्माण तिथि से पहले की तारीख है।
जैकब व्लिजम

1
@demongolem हाँ, CentOS संस्करण विकल्प dfका समर्थन नहीं करता है --output। उस स्थिति में, आप उस लाइन को बदल सकते हैं fs=$(df foo | awk '{a=$1}END{print a}'और फ़ंक्शन भी काम करेगा। इस उत्तर में मैं जो कुछ भी दिखा रहा हूं, वह एक तरह से स्वीकृत उत्तर से कमांड को लपेटने का एक तरीका है, जिसे सीधे फ़ाइल / निर्देशिका लक्ष्य के लिए चलाया जा सकता है।
terdon

11

statनिर्माण समय दिखाने में असमर्थता stat(2)सिस्टम कॉल की सीमा के कारण है , जिसकी वापसी संरचना में निर्माण समय के लिए फ़ील्ड शामिल नहीं है। लिनक्स 4.11 (यानी, 17.10 और नए *) के साथ शुरू, हालांकि, नया statx(2)सिस्टम कॉल उपलब्ध है, जिसमें इसकी वापसी संरचना में एक निर्माण समय शामिल है।

* और संभवतया पुराने एलटीएस पर हार्डवेयर सक्षमता स्टैक (एचडब्ल्यूई) गुठली का उपयोग करके रिलीज होता है। uname -rयह देखने के लिए जांचें कि क्या आप पुष्टि करने के लिए कम से कम 4.11 पर कर्नेल का उपयोग कर रहे हैं।

दुर्भाग्य से, सिस्टम कॉल को सीधे सी प्रोग्राम में कॉल करना आसान नहीं है। आमतौर पर 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

सिद्धांत रूप में, इससे सृजन का समय और अधिक सुलभ हो जाना चाहिए:

  • अधिक फाइल सिस्टम को केवल ext * वाले की तुलना में समर्थित होना चाहिए ( debugfsext2 / 3/4 filesystems के लिए एक उपकरण है, और दूसरों के लिए अनुपयोगी है)
  • आपको इसका उपयोग करने के लिए रूट की आवश्यकता नहीं है (कुछ आवश्यक पैकेजों, जैसे 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 और एक्सफ़ैट के लिए काम नहीं करता था। मुझे लगता है कि उन लोगों के लिए FUSE फाइल सिस्टम में सृजन समय शामिल नहीं था।


यदि, या बल्कि जब, ग्लिबेक statx(2)सिस्टम कॉल के लिए समर्थन जोड़ता है , statजल्द ही पालन करेगा और हम इसके लिए सादे पुराने statकमांड का उपयोग करने में सक्षम होंगे । लेकिन मुझे नहीं लगता कि यह एलटीएस रिलीज के लिए वापस किया जाएगा, भले ही वे नई गुठली प्राप्त करें। तो, मैं उम्मीद नहीं है statपर किसी भी वर्तमान LTS रिहाई कभी मैन्युअल हस्तक्षेप के बिना निर्माण के समय मुद्रित करने के लिए (14.04, 16.04 या 18.04)।

18.10 पर, हालांकि, आप सीधे statxवर्णित फ़ंक्शन का उपयोग कर सकते हैं man 2 statx(ध्यान दें कि 18.10 मैनपेज यह बताने में गलत है कि ग्लिब्क ने अभी तक आवरण नहीं जोड़ा है)।


जीथुब से जोड़ने के लिए धन्यवाद। मैंने कुछ महीनों पहले खोजा था जब 4.11 बाहर आया था और कुछ भी नहीं मिला और फिर इसके बारे में भूल गया।
विनयुनुच्स 2 यूनिक्स

@ WinEunuuchs2unix पिंग करके माफ़ करते हैं लेकिन क्या मेटा साइट पर यह पूछना बुद्धिमानी होगी कि मुरू के खाते में सिर्फ एक प्रतिनिधि क्यों है 1?
जॉर्ज उदेन

@GeorgeUdosen चौंकाने वाला है! मेरे पास एक कूबड़ क्यों है, हालांकि ...
WinEunuuchs2Unix 15

@GeorgeUdosen सामान्य रूप से निलंबन के बारे में हाल ही में एक मेटा सवाल है और वे एक विशिष्ट उपयोगकर्ता को संबोधित नहीं करेंगे: meta.askubuntu.com/questions/18341/… अब मैं चैट रूम में जा रहा हूं ताकि आप वहां बातचीत कर सकें तमन्ना।
विनयुनुच्स 2 यूनिक्स 17

अब जब यह सुविधा उपलब्ध है, तो क्या आप जानते हैं कि उस क्षेत्र को कैसे संशोधित किया जाए? मैं इसे अजगर में करने के लिए एक ctypes आवरण बनाने की कोशिश कर सकता हूं। धन्यवाद।
ग्रिंगो ने

3

TL; DR: बस चलाएं: sudo debugfs -R 'stat /path/to/your/file' /dev/<your fs>

(अपने एफएस का पता लगाने के लिए, भागो df -T /path/to/your/file, सबसे अधिक संभावना है कि यह होने जा रहा है /dev/sda1)।

दीर्घ संस्करण:

हम दो कमांड चलाने जा रहे हैं:

  1. अपनी फ़ाइल के विभाजन नाम का पता लगाएं।

    df -T /path/to/your/file

    आउटपुट इस तरह दिखने वाला है (विभाजन नाम पहले है):

    Filesystem     Type 1K-blocks    Used Available Use% Mounted on
    /dev/<your fs> ext4   7251432 3481272   3509836  50% /
    
  2. उस फ़ाइल का निर्माण समय ज्ञात करें।

    sudo debugfs -R 'stat /path/to/your/file' /dev/<your fs>
    

    आउटपुट में, देखें ctime

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.