कैसे / usr / bin / env को पता है कि किस प्रोग्राम का उपयोग करना है?


62

जब मैं #!/usr/bin/env pythonस्क्रिप्ट चलाने के लिए शेबंग का उपयोग करता हूं , तो सिस्टम को कैसे पता चलेगा कि किसका pythonउपयोग करना है? अगर मैं pythonपर्यावरण चर में एक बिन रास्ते की तलाश करता हूं तो मुझे कुछ नहीं मिलता है।

env | grep -i python

6
ओह, मुझे लगता है कि मैं इसे समझ
गया-

मैं इसके बारे में सोच रहा हूँ। और क्यों / usr / bin / env? / बिन / एनवी या एनवी के विपरीत, अगर यह सिर्फ एनवी से रास्तों की सूची प्राप्त कर रहा है?
फहीम मीठा

सिर्फ 'एनवी' काम नहीं करेगा क्योंकि इसमें पूरा रास्ता होना चाहिए। 'Env' प्रोग्राम आमतौर पर / user / bin / env में पाया जाता है। कुछ डिस्ट्रोस पर इसे / bin / env के रूप में भी पाया जा सकता है, लेकिन यह / usr / bin / env के साथ जाना सुरक्षित है।
मई'11

जवाबों:


54

शेबबैंग को दुभाषिया के लिए एक पूर्ण मार्ग की उम्मीद है ताकि निम्नलिखित सिंटैक्स का उपयोग गलत हो।

#!python

इस तरह काम कर सकते हैं एक पूर्ण पथ की स्थापना:

#!/usr/local/bin/python

लेकिन गैर पोर्टेबल होना के रूप में स्थापित किया जा सकता है अजगर में हैं /bin, /opt/python/binया जहाँ भी अन्य स्थान।

का उपयोग करते हुए env

#!/usr/bin/env python

एक तरीका है जो पोर्टेबल तरीके से ओएस को निर्दिष्ट करने के लिए अनुमति देता है एक पूर्ण पथ उसी के बराबर है जहां pythonपहली बार स्थित है PATH


56

कुटिया लाइन ( "तेज बैंग", यानी से #!) कर्नेल द्वारा संसाधित किया जाता है। कर्नेल पर्यावरण चर जैसे कि के बारे में जानना नहीं चाहता है PATH। तो शेबांग लाइन पर नाम एक निष्पादन योग्य के लिए एक पूर्ण पथ होना चाहिए। आप स्क्रिप्ट नाम से पहले उस निष्पादन योग्य को पास करने के लिए एक अतिरिक्त तर्क भी निर्दिष्ट कर सकते हैं (सिस्टम-निर्भर प्रतिबंधों के साथ मैं यहां नहीं जाऊंगा)। उदाहरण के लिए, पायथन लिपि के लिए, आप निर्दिष्ट कर सकते हैं

#!/usr/bin/python

पहली पंक्ति पर, और जब आप स्क्रिप्ट निष्पादित करते हैं, तो कर्नेल वास्तव में निष्पादित होगा /usr/bin/python /path/to/script। लेकिन यह सुविधाजनक नहीं है: आपको कमांड के पूर्ण पथ को निर्दिष्ट करने की आवश्यकता है। क्या अगर आपके पास pythonमें /usr/binकुछ मशीनों पर और /usr/local/binदूसरों पर? या फिर आप अपने सेट करना चाहते PATHकरने के लिए /home/joe/opt/python-2.5/binइतनी के रूप में अजगर का एक विशेष संस्करण उपयोग कैसे करें? चूंकि कर्नेल PATHआपके लिए लुकअप नहीं करेगा , इसलिए विचार यह है कि कर्नेल को एक कमांड चलाया जाए जो बदले में वांछित दुभाषिया को देखता है PATH:

#!/fixed/path/to/path-lookup-command python

यही कारण है कि path-lookup-commandएक तर्क के रूप एक निष्पादन के नाम ले लेना चाहिए और इसे देखो PATHऔर यह निष्पादित करें: गिरी चलेंगे /fixed/path/to/path-lookup-command python /path/to/script। जैसा कि होता है, envकमांड बस यही करता है। इसका मुख्य उद्देश्य एक अलग वातावरण के साथ एक कमांड को चलाना है, लेकिन चूंकि यह कमांड नाम को देखता है $PATH, इसलिए यह हमारे उद्देश्य के लिए एकदम सही है।

यद्यपि यह आधिकारिक रूप से गारंटी नहीं है, लेकिन ऐतिहासिक यूनिक्स सिस्टम और आधुनिक सिस्टम प्रदान किए envगए हैं /usr/bin, जिनके व्यापक उपयोग के कारण उस स्थान को ठीक रखा गया है #!/usr/bin/env। तो, व्यवहार में, यह निर्दिष्ट करने का तरीका है कि स्क्रिप्ट को उपयोगकर्ता के पसंदीदा पायथन इंटरप्रेटर द्वारा निष्पादित किया जाना चाहिए

#!/usr/bin/env python

2
किसके बीच पसंद किया जाता है envऔर which? चूंकि मेरे PATH वातावरण से सबसे योग्य निष्पादन योग्य भी प्राप्त होगा।
निखिल मुल्ले

8
@ निखिलमुले whichनिष्पादन योग्य पाता है और अपनी राह प्रिंट करता है। envपहले तर्क द्वारा निर्दिष्ट कार्यक्रम पाता है और इसे निष्पादित करता है, इसे शेष तर्क पास करता है।
केविन

3
इसलिए यह अनिवार्य रूप envसे एक स्पष्ट संस्करण है which
निखिल मुल्ले

6

सही है, तो चलाएं:

env | grep PATH

आपकी $ PATH निर्देशिकाओं की एक सूची है। यूनिक्स निर्देशिका की उस सूची से गुजरेगा, जब तक कि उसे "अजगर" नहीं मिल जाता।

आप यह देख सकते हैं कि यह कौन सी डायरेक्टरी को 'कौन सी' कमांड के साथ मिलती है:

which python

दिलचस्प बात यह है कि मैं sys.pathसक्रिय एनव $ env python3 ( ['', '/home/user/test', '/usr/lib/python3.4', '/usr/lib/python3.4/plat-x86_64-linux-gnu', '/usr/lib/python3.4/lib-dynload', '/home/user/.local/lib/python3.4/site-packages', '/usr/lib/python3.4/site-packages', '/usr/local/lib/python3.4/dist-packages', '/usr/lib/python3/dist-packages']और ./env/bin/python3 (['', '/home/user/test', '/usr/lib/python3.4', '/usr/lib/python3.4/plat-x86_64-linux-gnu', '/usr/lib/python3.4/lib-dynload', '/home/user/test/env3/lib/python3.4/site-packages']) के बीच अजगर में अंतर देख रहा हूं ।
थोरसुमोनर
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.