फ़ाइल सिस्टम को नेविगेट करते समय यूनिक्स उपयोगकर्ता की कार्यशील निर्देशिका का ट्रैक कैसे रखता है?


29

कहो कि मैं एक यूनिक्स प्रणाली पर एक शेल में लॉग इन करता हूं और कमांड को टैप करना शुरू करता हूं। मैं शुरू में अपने उपयोगकर्ता के घर निर्देशिका में शुरू करता हूं ~। मैं वहाँ से cdनीचे निर्देशिका के लिए हो सकता है Documents

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

हालाँकि, मैं जिस चीज में दिलचस्पी रखता हूं, वह यह है कि जब मैं निर्देशिका को, यानी माता-पिता या माता-पिता के माता-पिता को नेविगेट करता हूं तो वही प्रक्रिया कैसे काम करती है।

मेरे अज्ञात, संभवतः "अंधे" स्थान को देखते हुए, Documentsउस फ़ाइल के साथ पूरी फ़ाइल सिस्टम ट्री में संभवतः कई निर्देशिकाओं में से एक, यूनिक्स कैसे निर्धारित करता है कि मुझे अगले कहाँ रखा जाना चाहिए? क्या यह एक संदर्भ बनाता है pwdऔर इसकी जांच करता है? यदि हाँ, pwdतो वर्तमान नौवहन स्थिति को कैसे ट्रैक करता है ?


जवाबों:


76

अन्य उत्तर ओवरसिम्प्लीफिकेशन हैं, प्रत्येक कहानी के कुछ हिस्सों को प्रस्तुत करते हैं, और कुछ बिंदुओं पर गलत हैं।

कार्य निर्देशिका को ट्रैक करने के दो तरीके हैं :

  • हर प्रक्रिया के लिए, उस प्रक्रिया का प्रतिनिधित्व करने वाले कर्नेल-स्पेस डेटा संरचना में, कर्नेल दो vnode संदर्भों को कार्यशील निर्देशिका के vnodes और उस प्रक्रिया के रूट निर्देशिका के लिए संग्रहीत करता है। पूर्व संदर्भ द्वारा chdir()और fchdir()बाद में सिस्टम कॉल द्वारा सेट किया गया है chroot()। एक उन्हें परोक्ष रूप से /procलिनक्स ऑपरेटिंग सिस्टम पर या fstatFreeBSD पर कमांड के माध्यम से और इस तरह देख सकते हैं:

    % fstat -p $$ | हेड-एन 5
    USER CMD PID FD MOUNT INUM MODE SZ | DV R / W
    जेडेबीपी ज़श 92648 टेक्स्ट / 24958 -आर-एक्सआर-एक्सआर-एक्स 702360 आर
    जेडीबीपी ज़श 92648 शेट्टी / देव 148 करोड़ - w ---- पीटीएस / 4 आरडब्ल्यू
    JdeBP zsh 92648 wd / usr / home / JdeBP 4 drwxr-xr-x r
    JdeBP zsh 92648 रूट / 4 drwxr-xr-x 35 आर
    % 

    जब पथनाम रिज़ॉल्यूशन संचालित होता है, तो यह उन संदर्भित vnodes में से एक या दूसरे पर शुरू होता है, चाहे वह मार्ग सापेक्ष हो या निरपेक्ष। ( …at()सिस्टम कॉल का एक परिवार है जो एक ओपन (डायरेक्टरी) फ़ाइल डिस्क्रिप्टर द्वारा तीसरे विकल्प के रूप में संदर्भित vnode पर आरंभ करने के लिए मार्गनाम रिज़ॉल्यूशन की अनुमति देता है।)

    माइक्रो कर्नेल में डेटा संरचना अनुप्रयोग स्थान में है, लेकिन इन निर्देशिकाओं के लिए खुला संदर्भ रखने का सिद्धांत समान है।

  • आंतरिक रूप से, Z, Korn, Bourne Again, C और Almquist शेल जैसे गोले के भीतर, शेल अतिरिक्त रूप से आंतरिक स्ट्रिंग चर के स्ट्रिंग हेरफेर का उपयोग करके कार्य निर्देशिका का ट्रैक रखता है। जब भी यह कॉल करने का कारण होता है तो यह ऐसा करता है chdir()

    यदि कोई सापेक्ष पथनाम में बदलता है, तो यह उस नाम को जोड़ने के लिए स्ट्रिंग में हेरफेर करता है। यदि कोई एक पूर्ण पथनाम में बदलता है, तो वह स्ट्रिंग को नए नाम से बदल देता है। दोनों ही मामलों में, यह स्ट्रिंग को हटाने .और ..घटकों को समायोजित करता है और प्रतीकात्मक लिंक को उनके लिंक्ड-इन नामों के साथ बदलने का पीछा करता है। ( उदाहरण के लिए, यहाँ Z शेल कोड है ।)

    आंतरिक स्ट्रिंग चर में नाम एक शेल चर नाम से ट्रैक किया जाता है PWD(या cwdसी शेल में)। यह पारंपरिक रूप से एक पर्यावरण चर (नाम PWD) के रूप में शेल द्वारा उत्पन्न कार्यक्रमों के लिए निर्यात किया जाता है ।

चीजों को ट्रैक करने की ये दो विधियाँ निर्मित और शेल कमांडों के विकल्पों -Pऔर -Lविकल्पों द्वारा cdऔर pwdशेल के बिल्ट-इन pwdकमांड्स और दोनों कमांड्स और /bin/pwdबिल्ट-इन pwdकमांड्स जैसे कि (अन्य के बीच) के अंतर से पता चलती हैं। VIM और NeoVIM।

% mkdir a; ln -sab 
% (cd b; pwd; / bin / pwd; printenv PWD)
/ Usr / घर / JdeBP / b
/ Usr / घर / JdeBP / एक
/ Usr / घर / JdeBP / b
% (cd b; pwd -P; / बिन / pwd -P)
/ Usr / घर / JdeBP / एक
/ Usr / घर / JdeBP / एक
% (cd b; pwd -L; / bin / pwd -L)
/ Usr / घर / JdeBP / b
/ Usr / घर / JdeBP / b
% (cd -P b; pwd; / bin / pwd; Printenv PWD)
/ Usr / घर / JdeBP / एक
/ Usr / घर / JdeBP / एक
/ Usr / घर / JdeBP / एक
% (cd b; PWD = / hello / there / bin / pwd -L)
/ Usr / घर / JdeBP / एक
% 

जैसा कि आप देख सकते हैं: "लॉजिकल" वर्किंग डायरेक्टरी प्राप्त करना PWDशेल वेरिएबल (या एनवायरनमेंट वेरिएबल अगर कोई शेल नहीं है) को देखने का विषय है; "फिजिकल" वर्किंग डायरेक्टरी प्राप्त करने के दौरान getcwd()लाइब्रेरी फ़ंक्शन को कॉल करने का विषय है ।

/bin/pwdजब -Lविकल्प का उपयोग किया जाता है तो कार्यक्रम का संचालन कुछ सूक्ष्म होता है। यह पर्यावरण चर के मूल्य पर भरोसा नहीं कर सकता हैPWD जो इसे विरासत में मिला है। आखिरकार, इसे एक शेल द्वारा लागू करने की आवश्यकता नहीं है और हस्तक्षेप करने वाले कार्यक्रमों ने शेल के तंत्र को लागू नहीं किया हो सकता है ताकि PWDपर्यावरण चर हमेशा काम करने वाले निर्देशिका के नाम को ट्रैक कर सके। या कोई ऐसा कर सकता है जो मैंने वहीं किया था।

तो यह क्या करता है (जैसा कि POSIX मानक कहता है) यह जांचें कि नाम में दिया गया नाम PWDएक ही चीज़ का नाम देता है ., जैसा कि सिस्टम कॉल ट्रेस के साथ देखा जा सकता है:

% ln -sac 
% (cd b; ट्रस / बिन / pwd -L 3> & 1 1> & 2 2> & 3 | grep -E '^ स्टेट | __getcwd') 
स्टेट ("usr / home / JdeBP / b", { mode = drwxr-xr-x, inode = 120932, size = 2, blksize = 131072}) = 0 (0x0) 
स्टेट ("।", {mode = drwxr-xr-x, inode = 120932, size = 2, blksize = 131072}) = 0 (0x0)
/ Usr / घर / JdeBP / b
% (cd b; PWD = / usr / local / etc ट्रस / बिन / pwd -L 3> और 1 1> & 2 2> & 3 | grep -E '^ स्टेट | __getcwd': 
"" / usr / local / etc " , {विधा = drwxr-xr-x, inode = 14835, size = 158, blksize = 10240}) = 0 (0x0) 
स्टेट ("।", {मोड = drwxr-xr-x, इनोड = 120932, आकार = 2 , blksize = 131072}) = 0 (0x0)
__getcwd ("/ usr / होम / JdeBP / a", 1024) = 0 (0x0)
/ Usr / घर / JdeBP / एक
% (cd b; PWD = / hello / there truss / bin / pwd -L 3> & 1 1> & 2 2> & 3 | grep -E '^ stat | __getcwd') 
stat ("/ hello / there", 0x7fffffe73030) ERR # 2 'ऐसी कोई फ़ाइल या निर्देशिका' 
__getcwd ("/ usr / home / JdeBP / a", 1024) = 0 (0x0)
/ Usr / घर / JdeBP / एक
% (cd b; PWD = / usr / home / JdeBP / c truss / bin / pwd -L 3> & 1 1> & 2 2> & 3 | grep -E '^ स्टेट | __getwwd') 
स्टेट ("/ usr / home / home /" JdeBP / c ", {mode = drwxr-xr-x, inode = 120932, size = 2, blksize = 131072}) = 0 (0x0) 
स्टेट ("। ", {मोड} drwxr-xr-x, इनोड = 120932। , आकार = 2, blksize = 131072}) = 0 (0x0)
/ Usr / घर / JdeBP / सी
%

जैसा कि आप देख सकते हैं: यह केवल कॉल करता है getcwd()अगर यह एक बेमेल का पता लगाता है; और इसे PWDएक स्ट्रिंग पर सेट करके बेवकूफ बनाया जा सकता है जो वास्तव में एक ही निर्देशिका का नाम देता है, लेकिन एक अलग मार्ग से।

getcwd()पुस्तकालय समारोह अपने आप में एक विषय है। लेकिन précis:

  • मूल रूप से यह एक लाइब्रेरी फंक्शन था, जिसने वर्किंग डाइरेक्टरी से रूट पर वापस जाकर रूट में वर्किंग डायरेक्टरी को बार-बार देखने की कोशिश की ..। यह तब बंद हो गया जब यह एक लूप तक पहुंच ..गया जहां इसकी कार्यशील निर्देशिका के समान था या जब अगले ..अप को खोलने की कोशिश करने में कोई त्रुटि थी । यह कवर के तहत बहुत सारे सिस्टम कॉल होंगे।
  • आजकल स्थिति थोड़ी अधिक जटिल है। FreeBSD, उदाहरण के लिए (यह रूप में अच्छी तरह अन्य ऑपरेटिंग सिस्टम के लिए सच किया जा रहा है), यह है एक सच्चे प्रणाली अधिकार, के रूप में आप सिस्टम कॉल पहले दिया ट्रेस में देख सकते हैं। कार्यशील निर्देशिका vnode से रूट तक के सभी ट्रैवर्सल एक ही सिस्टम कॉल में किए जाते हैं, जो कि कर्नेल मोड कोड के डायरेक्ट एक्सेस के लिए डायरेक्ट्री एंट्री कैशे जैसी चीजों का लाभ उठाते हैं, ताकि pathname घटक लुकअप को अधिक कुशलता से कर सकें।

    हालाँकि, ध्यान दें कि FreeBSD और उन अन्य ऑपरेटिंग सिस्टमों पर भी कर्नेल एक स्ट्रिंग के साथ कार्य निर्देशिका का ट्रैक नहीं रखता है।

..फिर से नेविगेट करना अपने आप में एक विषय है। एक और précis: हालांकि निर्देशिकाएं पारंपरिक रूप से (यद्यपि, जैसा कि पहले से ही बताया गया है, इसकी आवश्यकता नहीं है) ..डिस्क पर निर्देशिका डेटा संरचना में वास्तविक है, कर्नेल प्रत्येक निर्देशिका के मूल निर्देशिका को ट्रैक करता है जो स्वयं vnode है और इस प्रकार ..किसी भी vnode में नेविगेट कर सकता है कार्यकारी डाइरेक्टरी। यह माउंटपॉइंट और परिवर्तित रूट तंत्र द्वारा कुछ जटिल है, जो इस उत्तर के दायरे से परे हैं।

अलग

Windows NT वास्तव में एक समान काम करता है। एक कार्यशील प्रति निर्देशिका है, जो SetCurrentDirectory()एपीआई कॉल द्वारा निर्धारित की जाती है और कर्नेल द्वारा उस निर्देशिका में एक (आंतरिक) ओपन फाइल हैंडल के माध्यम से प्रति प्रक्रिया ट्रैक की जाती है; और पर्यावरण चर का एक सेट है जो Win32 प्रोग्राम (न केवल कमांड इंटरप्रेटर्स, बल्कि सभी Win32 प्रोग्राम्स) कई वर्किंग डाइरेक्टरीज़ (एक प्रति ड्राइव) के नामों को ट्रैक करने के लिए उपयोग करते हैं, जब भी वे डायरेक्टरी बदलते हैं या उन्हें अधिलेखित करते हैं।

परंपरागत रूप से, यूनिक्स और लिनक्स ऑपरेटिंग सिस्टम के मामले के विपरीत, Win32 प्रोग्राम इन पर्यावरण चर को उपयोगकर्ताओं के लिए प्रदर्शित नहीं करते हैं। एक व्यक्ति कभी-कभी विंडोज एनटी पर चलने वाले यूनिक्स जैसे सबसिस्टम में उन्हें देख सकता है, हालांकि, साथ ही साथ SETएक विशेष तरीके से कमांड दुभाषियों के आदेशों का उपयोग करके भी ।

आगे की पढाई


1
यह मेरी अपेक्षा से कहीं अधिक है। धन्यवाद, और आगे पढ़ने के लिए अतिरिक्त धन्यवाद!
ReactingToAngularVues

doc.cat-v.org/plan_9/4th_edition/papers/lexnames प्लॉन.. 9 के संदर्भ में कुछ समस्याओं के बारे में बात करते हैं ,
इकारस

@ जेडेबीपी: शायद मुझे कुछ याद आ रहा है। आप कहते हैं, "आंतरिक रूप से, भीतर, बैश, ... और ..., शेल अतिरिक्त रूप से एक आंतरिक स्ट्रिंग चर के स्ट्रिंग हेरफेर का उपयोग करके कार्यशील निर्देशिका का ट्रैक रखता है। …, यह स्ट्रिंग को हटाने .और ..घटकों को समायोजित करता है और प्रतीकात्मक लिंक को उनके लिंक्ड-इन नामों के साथ बदलने का पीछा करता है। ... आंतरिक स्ट्रिंग चर में नाम को शेल चर नाम से ट्रैक किया जाता है PWD... "(जोर दिया)। … (Cont'd)
जी-मैन का कहना है कि मोनिका '

(Cont'd) ... लेकिन आपका उदाहरण एक आदेश के बाद PWD= दिखाता है , भले ही एक प्रतीकात्मक लिंक है - इसलिए शेल लिंक का "पीछा" नहीं करता है । क्या आपने गलत किया, या मैंने गलत किया? …/bcd bbaa -> b
जी-मैन का कहना है कि 'मोनिका'

मैं बस एक साइड पॉइंट पर गया, और आपको विवरण के लिए कोड की ओर इशारा किया। कब और कैसे वे प्रतीकात्मक लिंक का पीछा करते हैं या नहीं, इसके लिए विभिन्न शेल मैनुअल देखें। जेड खोल handily, इसके खोल विकल्प है कि निर्णय सूत्र का एक हिस्सा है कहता है CHASE_LINKS
JdeBP

1

कर्नेल निर्देशिका या फ़ाइल नामों पर नज़र नहीं रखता है; एक फ़ाइल या निर्देशिका को इनोड / डिवाइस युग्म द्वारा कर्नेल में दर्शाया गया है। जैसे सिस्टम कॉल chdir(), open()आदि (जैसे पैरामीटर के रूप में एक रास्ता है, जो पूर्ण हो सकता है ले /etc/passwd), या वर्तमान निर्देशिका के सापेक्ष (उदाहरण: Documents, ..)। जब कोई प्रक्रिया निष्पादित होती है chdir("Documents"), Documentsतो वर्तमान कामकाजी निर्देशिका के लिए एक लुकअप किया जाता है , और इस निर्देशिका को संदर्भित करने के लिए प्रक्रिया की कार्यशील निर्देशिका को अपडेट किया जाता है। कर्नेल के दृष्टिकोण से, ".." नाम में कुछ भी विशेष नहीं है, यह फाइल सिस्टम में केवल एक सम्मेलन ..है जो मूल निर्देशिका को संदर्भित करता है।

getcwd()समारोह के लिए एक प्रणाली कॉल, लेकिन रूट निर्देशिका में अपनी तरह से काम करने के लिए, रास्ते में पथ घटकों के नाम की रिकॉर्डिंग है कि एक पुस्तकालय कार्य नहीं है।


0

दिलचस्प है, पारंपरिक रूप cd ..से बहुत अधिक सरल है pwd। नामांकित निर्देशिकाओं ..को फ़ाइल सिस्टम में स्पष्ट रूप से रखा गया है। सिस्टम वर्तमान निर्देशिका के डिवाइस / इनकोड का ट्रैक रखता है, इसलिए cd ..या अधिक सटीक रूप से सिस्टम कॉल chdir("..")बस नाम की तलाश में "" .. "को चालू निर्देशिका के इनोड से संबंधित फाइल में बदल देता है और वर्तमान निर्देशिका के डिवाइस / इनकोड को बदल देता है।" मूल्य वहाँ पाया।

pwd(अधिक सटीक रूप से /bin/pwd) ..क्रमिक रूप से लिंक का अनुसरण करता है और संबंधित निर्देशिकाओं को तब तक पढ़ता है जब तक कि वह इनोड को खोजने से नहीं आता है, जो उन नामों की सूची को रिवर्स में तब तक असेंबल करता है जब तक कि वह रूट डायरेक्टरी तक नहीं पहुंचता (विशेष रूप से एक ..प्रविष्टि नहीं होती )।

अब यह मूल निम्न-स्तरीय मूल व्यवहार है। pwdइसके बजाय वास्तविक शेल कमांड वर्तमान पथ नाम को कैशिंग करने वाली विभिन्न तकनीकों पर निर्भर करते हैं। लेकिन मूल रूप से, यह केवल इसकी जड़ है जो वास्तव में ज्ञात है। तात्पर्य यह है कि एक बार सहानुभूति का उपयोग निर्देशिकाओं को नेविगेट करने के लिए किया जाता है, वर्तमान कार्य निर्देशिका नाम शेल की वर्तमान धारणा और सिस्टम का /bin/pwdविचलन हो सकता है।

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