क्या एक शेबबैंग होना संभव है, जो एक दुभाषिया के लिए एक मार्ग निर्दिष्ट करने के बजाय, इसमें दुभाषिया का नाम है, और शेल इसे $ PATH के माध्यम से खोजने देता है?
यदि नहीं, तो क्या इसका एक कारण है?
क्या एक शेबबैंग होना संभव है, जो एक दुभाषिया के लिए एक मार्ग निर्दिष्ट करने के बजाय, इसमें दुभाषिया का नाम है, और शेल इसे $ PATH के माध्यम से खोजने देता है?
यदि नहीं, तो क्या इसका एक कारण है?
जवाबों:
पीएटीएच लुकअप यूजरस्पेस में मानक सी लाइब्रेरी की एक विशेषता है, जैसा कि सामान्य रूप से पर्यावरण चर हैं। कर्नेल पर्यावरण चर को नहीं देखता है, सिवाय इसके कि जब वह execve
नई प्रक्रिया के कॉलर से वातावरण में गुजरता है।
कर्नेल में पथ पर कोई व्याख्या नहीं करता है execve
(यह आवरण कार्यों को execvp
करने के लिए है जैसे कि PATH लुकअप करने के लिए) या शेबबैंग में (जो execve
आंतरिक रूप से कॉल को कम या ज्यादा पुन: रूट करता है )। इसलिए आपको शेबंगो में निरपेक्ष मार्ग को अपनाने की आवश्यकता है। मूल कुटिया कार्यान्वयन सिर्फ कोड की कुछ लाइनें था, और यह काफी के बाद से नहीं विस्तार किया गया है।
यूनिक्स के पहले संस्करणों में, शेल ने खुद को आह्वान करने का काम किया था जब उसने देखा कि आप एक स्क्रिप्ट का आह्वान कर रहे हैं। कर्बेज में कई कारणों से शेबंग को जोड़ा गया था ( डेनिस रिची द्वारा औचित्य का सारांश :
पाथलेस शेबैंग को पर्यावरण चर और प्रक्रिया तक पहुँचने के लिए कर्नेल को बढ़ाने की आवश्यकता होगी PATH
, या कर्नेल को PATH लुकअप करने वाले यूजरस्पेस प्रोग्राम को निष्पादित करना होगा। पहली विधि में कर्नेल में जटिलता की एक विषम मात्रा को जोड़ने की आवश्यकता होती है। दूसरी विधि पहले से ही एक #!/usr/bin/env
शेबंग के साथ संभव है ।
A यदि आप एक सापेक्ष पथ डालते हैं, तो यह प्रक्रिया की वर्तमान निर्देशिका के लिए अपेक्षाकृत व्याख्या की जाती है (स्क्रिप्ट युक्त निर्देशिका नहीं), जो शायद ही किसी शबंग में उपयोगी है।
execve
को शेबंग में न तो निरपेक्ष पथ की आवश्यकता होती है, न ही हालांकि यह थोड़ा सा समझ में आता है कि शेबबैंग में एक सापेक्ष पथ है।
/lib64/ld-linux-x86-64.so.2
( ldd
आउटपुट देखें ) द्वारा "व्याख्या" किए जाते हैं । लिनक्स इसे पूरी तरह से सामान्य बनाता है: binfmt
समर्थन (2.1.43 के बाद से) आपको दुभाषिया-पथ / जादू-संख्या-या-फ़ाइल-एक्सटेंशन जोड़े को पंजीकृत करने देता है। आप PE32 हो सकता है .exe
रों आह्वान wine
जब आप उन्हें चलाने के लिए, जावा वर्ग और जार फ़ाइलों आह्वान java
, आदि आदि
आंख से मिलने से कहीं ज्यादा चल रहा है। #!
लाइनें यूनिक्स या लिनक्स कर्नेल द्वारा व्याख्या की जाती हैं, #!
गोले का एक पहलू नहीं है। इसका मतलब यह है कि PATH
वास्तव में उस समय मौजूद नहीं होता है जब कर्नेल यह तय करता है कि उसे क्या निष्पादित करना है।
सबसे सामान्य तरीका है कि यह जानने के लिए कि कौन से निष्पादन योग्य चलने के लिए, या perl
पोर्टेबल फैशन या इसी तरह से कॉल करने के लिए उपयोग करना है #!/usr/bin/env perl
। कर्नेल निष्पादित करता है /usr/bin/env
, जो एक PATH
पर्यावरण चर विरासत में मिला है । निष्पादन योग्य को चलाने के लिए कर्नेल प्राप्त करने के लिए सिस्टम कॉल env
में (इस उदाहरण में) पाता perl
है PATH
और उपयोग करता है ।execve(2)
perl
$ strace sleep 1
execve("/usr/bin/sleep", ["sleep", "1"], [/* 99 vars */]) = 0
पूर्ण पथ में रूपांतरण शेल द्वारा किया जाता है (अधिक सामान्य: उपयोगकर्ता स्थान में)। कर्नेल एक फ़ाइल नाम / पथ की अपेक्षा करता है जो सीधे पहुंच सकता है।
यदि आप चाहते हैं कि सिस्टम आपके निष्पादन योग्य को पाथ चर के माध्यम से ढूंढता है, तो आप अपने शेलबैंग को फिर से लिख सकते हैं #!/usr/bin/env EXEC
।
लेकिन इस मामले में भी यह कर्नेल नहीं है जो खोज करता है।
strace
( /usr/bin/strace
कुछ बिंदु पर परिवर्तित ) चल रहा है।