पथभ्रष्ट शेबांग का उपयोग क्यों नहीं किया जाता है?


24

क्या एक शेबबैंग होना संभव है, जो एक दुभाषिया के लिए एक मार्ग निर्दिष्ट करने के बजाय, इसमें दुभाषिया का नाम है, और शेल इसे $ PATH के माध्यम से खोजने देता है?

यदि नहीं, तो क्या इसका एक कारण है?


जवाबों:


20

पीएटीएच लुकअप यूजरस्पेस में मानक सी लाइब्रेरी की एक विशेषता है, जैसा कि सामान्य रूप से पर्यावरण चर हैं। कर्नेल पर्यावरण चर को नहीं देखता है, सिवाय इसके कि जब वह execveनई प्रक्रिया के कॉलर से वातावरण में गुजरता है।

कर्नेल में पथ पर कोई व्याख्या नहीं करता है execve(यह आवरण कार्यों को execvpकरने के लिए है जैसे कि PATH लुकअप करने के लिए) या शेबबैंग में (जो execveआंतरिक रूप से कॉल को कम या ज्यादा पुन: रूट करता है )। इसलिए आपको शेबंगो में निरपेक्ष मार्ग को अपनाने की आवश्यकता है। मूल कुटिया कार्यान्वयन सिर्फ कोड की कुछ लाइनें था, और यह काफी के बाद से नहीं विस्तार किया गया है।

यूनिक्स के पहले संस्करणों में, शेल ने खुद को आह्वान करने का काम किया था जब उसने देखा कि आप एक स्क्रिप्ट का आह्वान कर रहे हैं। कर्बेज में कई कारणों से शेबंग को जोड़ा गया था ( डेनिस रिची द्वारा औचित्य का सारांश :

  • कॉल करने वाले को यह चिंता करने की आवश्यकता नहीं है कि निष्पादित करने का कार्यक्रम शेल स्क्रिप्ट या देशी बाइनरी है।
  • स्क्रिप्ट स्वयं निर्दिष्ट करती है कि कॉल करने वाले के बजाय किस दुभाषिया का उपयोग करना है।
  • कर्नेल लॉग में स्क्रिप्ट नाम का उपयोग करता है।

पाथलेस शेबैंग को पर्यावरण चर और प्रक्रिया तक पहुँचने के लिए कर्नेल को बढ़ाने की आवश्यकता होगी PATH, या कर्नेल को PATH लुकअप करने वाले यूजरस्पेस प्रोग्राम को निष्पादित करना होगा। पहली विधि में कर्नेल में जटिलता की एक विषम मात्रा को जोड़ने की आवश्यकता होती है। दूसरी विधि पहले से ही एक #!/usr/bin/envशेबंग के साथ संभव है ।

A यदि आप एक सापेक्ष पथ डालते हैं, तो यह प्रक्रिया की वर्तमान निर्देशिका के लिए अपेक्षाकृत व्याख्या की जाती है (स्क्रिप्ट युक्त निर्देशिका नहीं), जो शायद ही किसी शबंग में उपयोगी है।


2
नहीं, कर्नेल execveको शेबंग में न तो निरपेक्ष पथ की आवश्यकता होती है, न ही हालांकि यह थोड़ा सा समझ में आता है कि शेबबैंग में एक सापेक्ष पथ है।
स्टीफन चेज़लस

3
किसी के लिए यह उत्सुक है कि "शेबंग आंतरिक रूप से कॉल को फिर से कैसे करे" के बारे में उत्सुक है: यह वास्तव में निष्पादकों पर चलने वाले दुभाषियों के लिए एक सामान्य तंत्र का हिस्सा है जिसकी उन्हें आवश्यकता है। डायनामिक रूप से जुड़े ईएलएफ निष्पादनयोग्य /lib64/ld-linux-x86-64.so.2( lddआउटपुट देखें ) द्वारा "व्याख्या" किए जाते हैं । लिनक्स इसे पूरी तरह से सामान्य बनाता है: binfmtसमर्थन (2.1.43 के बाद से) आपको दुभाषिया-पथ / जादू-संख्या-या-फ़ाइल-एक्सटेंशन जोड़े को पंजीकृत करने देता है। आप PE32 हो सकता है .exeरों आह्वान wineजब आप उन्हें चलाने के लिए, जावा वर्ग और जार फ़ाइलों आह्वान java, आदि आदि
पीटर Cordes

#! / usr / bin / env -S [shebang] मेरे लिए आवश्यक था कि मैं उसका रास्ता जाने बिना nvm का उपयोग करूं (nvm का उपयोग करके - जो मुझे मूल रूप से अपेक्षित की तुलना में एक अलग स्थान पर रखता है)।
TamusJRoyce

-S केवल कोरुटिल्स 8.30 के बाद से उपलब्ध है। Gitlab.com/gnuwget/wget/commit/… देखें ।
टिम रुएसेन रॉकडबूट

19

आंख से मिलने से कहीं ज्यादा चल रहा है। #!लाइनें यूनिक्स या लिनक्स कर्नेल द्वारा व्याख्या की जाती हैं, #!गोले का एक पहलू नहीं है। इसका मतलब यह है कि PATHवास्तव में उस समय मौजूद नहीं होता है जब कर्नेल यह तय करता है कि उसे क्या निष्पादित करना है।

सबसे सामान्य तरीका है कि यह जानने के लिए कि कौन से निष्पादन योग्य चलने के लिए, या perlपोर्टेबल फैशन या इसी तरह से कॉल करने के लिए उपयोग करना है #!/usr/bin/env perl। कर्नेल निष्पादित करता है /usr/bin/env, जो एक PATHपर्यावरण चर विरासत में मिला है । निष्पादन योग्य को चलाने के लिए कर्नेल प्राप्त करने के लिए सिस्टम कॉल envमें (इस उदाहरण में) पाता perlहै PATHऔर उपयोग करता है ।execve(2)perl


4
$ strace sleep 1
execve("/usr/bin/sleep", ["sleep", "1"], [/* 99 vars */]) = 0

पूर्ण पथ में रूपांतरण शेल द्वारा किया जाता है (अधिक सामान्य: उपयोगकर्ता स्थान में)। कर्नेल एक फ़ाइल नाम / पथ की अपेक्षा करता है जो सीधे पहुंच सकता है।

यदि आप चाहते हैं कि सिस्टम आपके निष्पादन योग्य को पाथ चर के माध्यम से ढूंढता है, तो आप अपने शेलबैंग को फिर से लिख सकते हैं #!/usr/bin/env EXEC

लेकिन इस मामले में भी यह कर्नेल नहीं है जो खोज करता है।


1
पूर्ण पथ में रूपांतरण शेल द्वारा किया जाता है धन्यवाद, हालांकि ... क्या उदाहरण को स्पष्ट करना चाहिए? जैसा कि मैंने देखा, शेल 2 तर्क के साथ बस strace( /usr/bin/straceकुछ बिंदु पर परिवर्तित ) चल रहा है।
एलोइस महदाल
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.