यदि लिनक्स पर सब कुछ एक फाइल है, तो निर्देशिका क्या है?


17

बहुत बार शुरुआती एक वाक्यांश "सब कुछ लिनक्स / यूनिक्स पर एक फ़ाइल है" सुनते हैं। हालाँकि, तब निर्देशिकाएं क्या हैं? वे फ़ाइलों से कैसे भिन्न हैं?

जवाबों:


22

नोट: मूल रूप से यह मेरे जवाब का समर्थन करने के लिए लिखा गया था क्यों lsकमांड में वर्तमान निर्देशिका को खुद से जुड़ा हुआ माना जाता है? लेकिन मुझे लगा कि यह एक ऐसा विषय है जो अपने दम पर खड़ा होना चाहता है और इसलिए यह प्रश्नोत्तर है

यूनिक्स / लिनक्स फाइल सिस्टम और फाइलों को समझना: सब कुछ एक इनकोड है

अनिवार्य रूप से, एक निर्देशिका सिर्फ एक विशेष फ़ाइल है, जिसमें प्रविष्टियों और उनकी आईडी की सूची है।

इससे पहले कि हम चर्चा शुरू करें, कुछ शब्दों के बीच अंतर करना और यह समझना महत्वपूर्ण है कि निर्देशिका और फाइलें वास्तव में क्या दर्शाती हैं। आपने यूनिक्स / लिनक्स के लिए "सब कुछ एक फ़ाइल है" अभिव्यक्ति सुनी होगी। खैर, जो उपयोगकर्ता अक्सर फ़ाइल के रूप में समझते हैं वह यह है: /etc/passwd- एक पथ और एक नाम के साथ एक वस्तु। वास्तव में, एक नाम (यह एक निर्देशिका या फ़ाइल, या जो कुछ भी हो) केवल पाठ की एक स्ट्रिंग है - वास्तविक वस्तु की एक संपत्ति। उस ऑब्जेक्ट को इनोड या I- नंबर कहा जाता है , और इनकोड तालिका में डिस्क पर संग्रहीत होता है। खुले कार्यक्रमों में इनोड टेबल भी होते हैं, लेकिन यह हमारी चिंता का विषय नहीं है।

यूनिक्स की एक निर्देशिका की धारणा के रूप में केन थॉम्पसन ने 1989 के साक्षात्कार में इसे रखा :

... और फिर उनमें से कुछ फाइलें, निर्देशिकाएं थीं जिनमें सिर्फ नाम और आई-संख्या शामिल थी।

1972 में डेनिस रिची की बातचीत से एक दिलचस्प अवलोकन किया जा सकता है

"... निर्देशिका वास्तव में एक फ़ाइल से अधिक नहीं है, लेकिन इसकी सामग्री सिस्टम द्वारा नियंत्रित की जाती है, और सामग्री अन्य फ़ाइलों के नाम हैं। (एक निर्देशिका को कभी-कभी अन्य प्रणालियों में कैटलॉग कहा जाता है।)"

... लेकिन बात में कहीं भी इनोड्स का जिक्र नहीं है। हालाँकि, राज्यों पर 1971 का मैनुअलformat of directories :

तथ्य यह है कि एक फ़ाइल एक निर्देशिका है, इसके आई-नोड प्रविष्टि के ध्वज शब्द में थोड़ा सा इंगित किया गया है।

निर्देशिका प्रविष्टियाँ 10 बाइट्स लंबी होती हैं। पहला शब्द i- नोड की प्रविष्टि द्वारा प्रस्तुत फ़ाइल का नोड है, यदि गैर-शून्य; यदि शून्य है, तो प्रविष्टि खाली है।

इसलिए यह शुरुआत से ही वहां है।

डायरेक्टरी और इनोड पेयरिंग को भी समझाया गया है कि UNIX फाइल सिस्टम में डायरेक्टरी स्ट्रक्चर्स को कैसे स्टोर किया जाता है? । एक निर्देशिका स्वयं एक डेटा संरचना है, और अधिक विशेष रूप से: उन वस्तुओं (अनुमतियों, प्रकार, मालिक, आकार, आदि) के बारे में सूचियों की ओर इशारा करते हुए वस्तुओं (फ़ाइलों और इनोड संख्या) की एक सूची। इसलिए प्रत्येक डायरेक्टरी में अपना स्वयं का आईनोड नंबर होता है, और फिर फाइलनेम और इनकोड नंबर। सबसे प्रसिद्ध इनोड # 2 है जो /निर्देशिका है । (ध्यान दें, हालांकि वे /devऔर /runआभासी फाइल सिस्टम हैं, इसलिए चूंकि वे अपने फाइल सिस्टम के लिए रूट फ़ोल्डर हैं, इसलिए उनके पास इनोड 2 भी हैं; यानी एक इनकोड अपने फाइल सिस्टम पर अद्वितीय है, लेकिन कई फाइल सिस्टम संलग्न होने के साथ, आपके पास गैर-अद्वितीय इनोडस हैं)। लिंक किए गए प्रश्न से उधार लिया गया आरेख संभवतः इसे अधिक स्पष्ट रूप से समझाता है:

निर्देशिका-inode-ब्लॉक

इनकोड में संग्रहीत सभी जानकारी stat()को लिनक्स के अनुसार सिस्टम कॉल के माध्यम से एक्सेस किया जा सकता है man 7 inode:

प्रत्येक फ़ाइल में फ़ाइल के बारे में मेटाडेटा वाला एक इनकोड होता है। कोई एप्लिकेशन इस मेटाडेटा को स्टेट (2) (या संबंधित कॉल) का उपयोग करके पुनः प्राप्त कर सकता है, जो एक स्टेट स्ट्रक्चर, या स्टैडेक्स (2) देता है, जो एक स्टेटेक्स स्ट्रक्चर को लौटाता है।

क्या किसी फ़ाइल को केवल उसके इनोड नंबर ( Ref1 , ref2 ) को जानने के लिए उपयोग करना संभव है ? कुछ यूनिक्स कार्यान्वयनों पर यह संभव है, लेकिन यह अनुमति और पहुंच जांच को दरकिनार कर देता है, इसलिए लिनक्स पर इसे लागू नहीं किया जाता है, और आपको find <DIR> -inum 1234फ़ाइल नाम और इसके संबंधित इनोड प्राप्त करने के लिए फाइलसिस्टम ट्री ( उदाहरण के लिए) को पार करना होगा ।

स्रोत कोड स्तर पर, यह लिनक्स कर्नेल स्रोत में परिभाषित किया गया है और इसे कई फाइल सिस्टमों द्वारा भी अपनाया गया है जो यूनिक्स / लिनक्स ऑपरेटिंग सिस्टम पर काम करते हैं, जिसमें ext3 और ext4 फाइल सिस्टम (उबंटू डिफ़ॉल्ट) शामिल हैं। दिलचस्प बात: डेटा सिर्फ जानकारी के ब्लॉक होने के साथ, लिनक्स में वास्तव में इनोड_इनिट_लव्स फ़ंक्शन होता है जो निर्धारित कर सकता है कि क्या एक इनोड एक पाइप ( inode->i_pipe) है। हां, सॉकेट और पाइप तकनीकी रूप से भी फाइल हैं - अनाम फाइलें, जिनमें डिस्क पर फ़ाइल नाम नहीं हो सकता है। FIFO और यूनिक्स-डोमेन सॉकेट्स में फाइल सिस्टम पर फाइलनेम हैं।

डेटा स्वयं अद्वितीय हो सकता है, लेकिन इनोड संख्या अद्वितीय नहीं हैं। अगर हमारे पास फोब्बर नामक फू की कड़ी है, तो यह 123 के साथ ही संकेत देगा। इस इनकोड में ही जानकारी होती है कि उस इनकोड के द्वारा डिस्क स्पेस के वास्तविक ब्लॉक पर क्या कब्जा है। और यह तकनीकी रूप से है कि आप .निर्देशिका फ़ाइल नाम से कैसे जुड़े हो सकते हैं । ठीक है, लगभग: आप लिनक्स पर निर्देशिकाओं के लिए हार्डलिंक नहीं बना सकते हैं , लेकिन फाइलसिस्टम बहुत ही अनुशासित तरीके से निर्देशिकाओं की हार्ड लिंक की अनुमति दे सकता है, जो केवल .और ..हार्ड लिंक होने का एक बाधा बनाता है ।

निर्देशिका ट्री

Filesystems ट्री डेटास्ट्रक्चर में से एक के रूप में एक डायरेक्टरी ट्री को लागू करते हैं। विशेष रूप से,

  • ext3 और ext4 HTree का उपयोग करते हैं
  • xfs B + ट्री का उपयोग करता है
  • zfs हैश ट्री का उपयोग करता है

यहां मुख्य बिंदु यह है कि निर्देशिकाएं एक पेड़ में नोड्स हैं, और उपनिर्देशिका बाल नोड्स हैं, प्रत्येक बच्चे के पास मूल नोड के लिए एक लिंक है। इस प्रकार, एक डायरेक्टरी लिंक के लिए इनकोड काउंट न्यूनतम 2 नंगे डायरेक्टरी (निर्देशिका नाम /home/example/और स्वयं से लिंक के लिए लिंक /home/example/.) के लिए न्यूनतम 2 है , और प्रत्येक अतिरिक्त उपनिर्देशिका एक अतिरिक्त लिंक / नोड है:

# new directory has link count of 2
$ stat --format=%h .
2
# Adding subdirectories increases link count
$ mkdir subdir1
$ stat --format=%h .
3
$ mkdir subdir2
$ stat --format=%h .
4
# Count of links for root
$ stat --format=%h /
25
# Count of subdirectories, minus .
$ find / -maxdepth 1 -type d | wc -l
24

इयान डी। एलन के पाठ्यक्रम पृष्ठ पर पाया गया आरेख एक सरलीकृत बहुत स्पष्ट आरेख दिखाता है:

WRONG - names on things      RIGHT - names above things
=======================      ==========================

    R O O T            --->         [etc,bin,home]   <-- ROOT directory
   /   |   \                         /    |      \
etc   bin   home       --->  [passwd]  [ls,rm]  [abcd0001]
 |   /   \    \                 |      /    \       |
 |  ls   rm  abcd0001  --->     |  <data>  <data>  [.bashrc]
 |               |              |                   |
passwd       .bashrc   --->  <data>                <data>

राइट आरेख में केवल एक चीज जो गलत है वह यह है कि फाइलों को तकनीकी रूप से डायरेक्टरी ट्री पर ही नहीं माना जाता है: किसी फाइल को जोड़ने से लिंक काउंट पर कोई प्रभाव नहीं पड़ता है:

$ mkdir subdir2
$ stat --format=%h .
4
# Adding files doesn't make difference
$ cp /etc/passwd passwd.copy
$ stat --format=%h .
4

निर्देशिका को एक्सेस करना मानो वे फ़ाइल हैं

लिनुस टोरवाल्ड्स को उद्धृत करने के लिए :

"सब कुछ एक फ़ाइल है" के साथ पूरे बिंदु यह नहीं है कि आपके पास कुछ यादृच्छिक फ़ाइल नाम है (वास्तव में, सॉकेट्स और पाइप दिखाते हैं कि "फ़ाइल" और "फ़ाइलनाम" का एक दूसरे से कोई लेना-देना नहीं है), लेकिन यह तथ्य कि आप आम का उपयोग कर सकते हैं विभिन्न चीजों पर काम करने के लिए उपकरण।

यह मानते हुए कि एक निर्देशिका केवल एक फ़ाइल का एक विशेष मामला है, स्वाभाविक रूप से एपीआई होना चाहिए जो हमें नियमित रूप से फाइलों के समान फैशन में उन्हें खोलने / पढ़ने / लिखने / बंद करने की अनुमति देता है ।

यही वह जगह dirent.hहै जहां सी लाइब्रेरी आती है, जो direntसंरचना को परिभाषित करती है, जिसे आप आदमी 3 में पा सकते हैं :

   struct dirent {
       ino_t          d_ino;       /* Inode number */
       off_t          d_off;       /* Not an offset; see below */
       unsigned short d_reclen;    /* Length of this record */
       unsigned char  d_type;      /* Type of file; not supported
                                      by all filesystem types */
       char           d_name[256]; /* Null-terminated filename */
   };

इस प्रकार, आपके सी कोड में आपको परिभाषित करना है struct dirent *entry_p, और जब हम एक निर्देशिका खोलते हैं opendir()और उसके साथ पढ़ना शुरू करते हैं readdir(), तो हम उस entry_pसंरचना में प्रत्येक आइटम को संग्रहीत करेंगे । बेशक, प्रत्येक आइटम में direntऊपर दिखाए गए टेम्प्लेट में परिभाषित फ़ील्ड होंगे ।

यह कैसे काम करता है इसका व्यावहारिक उदाहरण वर्तमान कार्य निर्देशिका में फ़ाइलों और उनके इनोड नंबरों को सूचीबद्ध करने के बारे में मेरे जवाब में पाया जा सकता है ।

ध्यान दें कि fdopen पर POSIX मैनुअल बताता है कि "[t] वह डॉट और डॉट-डॉट के लिए निर्देशिका प्रविष्टियाँ वैकल्पिक हैं" और रीडडीर मैनुअल स्टेट्स struct dirent केवल d_nameऔर d_inoफ़ील्ड के लिए आवश्यक हैं।

"लेखन" पर निर्देशिकाओं पर ध्यान दें: निर्देशिका में लिखना प्रविष्टियों की अपनी "सूची" को संशोधित कर रहा है। इसलिए, किसी फाइल को बनाना या हटाना डायरेक्ट्री राइट परमिशन से जुड़ा होता है और फाइल्स को जोड़ना / रिमूव करना उक्त डायरेक्टरी पर राइटिंग ऑपरेशन होता है।


2
मैं स्वीकार करने से इनकार करता हूं कि सॉकेट्स फाइलें हैं;) "क्या सब कुछ एक फ़ाइल के रूप में सुलभ है" अधिक सटीक होगा?
रिनजविंड

@ रिनविंड खैर, वाक्यांश "सब कुछ एक फ़ाइल के रूप में सुलभ है" सटीक है। नियमित फ़ाइलों में open()और read()सॉकेट्स भी हैं connect()और read()। क्या अधिक सटीक होगा कि डिस्क या मेमोरी पर संग्रहीत "फ़ाइल" वास्तव में "डेटा" है, और कुछ फाइलें अनाम हैं - उनका फ़ाइल नाम नहीं है। आमतौर पर उपयोगकर्ता डेस्कटॉप पर उस आइकन के संदर्भ में फाइलों के बारे में सोचते हैं, लेकिन यह एकमात्र ऐसी चीज नहीं है जो मौजूद है। यह भी देखें unix.stackexchange.com/a/116616/85039
सर्गी

यदि एक निर्देशिका एक फाइल थी तो अच्छी तरह से प्रश्न अधिक था। और यह है। FIFO नामांकित पाइप के साथ सॉकेट लगभग एक अलग प्रश्न हो सकता है।
विनयुनुच्स

खैर, मुझे अब तक पाइप के बारे में एक जवाब मिला: askubuntu.com/a/1074550/295286 हो सकता है कि फीफो आगे होगा
सर्गी कोलोडाज़नी
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.