सेट, निर्यात और एनवी के बीच क्या अंतर है और मुझे प्रत्येक का उपयोग कब करना चाहिए?


112

हर बार जब मैं एक बैश स्क्रिप्ट मारूंगा और यह मुझे एक चर सेट करने के कुछ तरीके हैं:

key=value
env key=value
export key=value

जब आप एक स्क्रिप्ट या एक कमांड के अंदर होते हैं (उदाहरण के लिए, मैं अक्सर वाइन लॉन्चर के साथ एक चर को सही वाइन उपसर्ग सेट करने के लिए श्रृंखला देता हूँ) ये पूरी तरह से विनिमेय प्रतीत होते हैं, लेकिन निश्चित रूप से ऐसा नहीं हो सकता है।

इन तीन तरीकों में क्या अंतर है और क्या आप मुझे एक उदाहरण दे सकते हैं कि मैं विशेष रूप से हर एक का उपयोग कब करना चाहता हूं?

निश्चित रूप से `VAR = ...` और `निर्यात VAR = ...` के बीच अंतर क्या है? लेकिन मैं यह जानना चाहता हूं कि इसमें कैसे envफिट बैठता है, और प्रत्येक के लाभ दिखाने वाले कुछ उदाहरण भी अच्छे होंगे :)


5
ध्यान दें कि export key=valueसिंटैक्स विस्तारित है और इसका उपयोग पोर्टेबल स्क्रिप्ट (यानी #! /bin/sh) में नहीं किया जाना चाहिए ।
साइमन रिक्टर

जवाबों:


110

आइए हम एक विशिष्ट उदाहरण पर विचार करें। grepआदेश के लिए एक वातावरण चर कहा उपयोग करता GREP_OPTIONSडिफ़ॉल्ट विकल्प सेट करने के लिए।

अभी। यह देखते हुए कि फ़ाइल test.txtमें निम्न पंक्तियाँ हैं:

line one
line two

कमांड चलाने से grep one test.txtवापस आ जाएगी

line one

यदि आप -vविकल्प के साथ grep चलाते हैं , तो यह गैर-मिलान लाइनों को लौटा देगा, इसलिए आउटपुट होगा

line two

अब हम पर्यावरण चर के साथ विकल्प सेट करने का प्रयास करेंगे।

  1. exportआपके द्वारा कॉल किए जा रहे आदेशों के वातावरण में बिना सेट किए गए पर्यावरण चर विरासत में नहीं मिलेंगे।

    GREP_OPTIONS='-v'
    grep one test.txt

    परिणाम:

    line one

    जाहिर है, विकल्प -vपास नहीं हुआ grep

    आप इस फॉर्म का उपयोग तब करना चाहते हैं जब आप केवल उपयोग करने के लिए शेल के लिए एक चर सेट कर रहे हैं, उदाहरण के लिए for i in * ; doआप निर्यात नहीं करना चाहते हैं $i

  2. हालांकि, चर को उस विशेष कमांड लाइन के वातावरण में पारित किया जाता है, इसलिए आप कर सकते हैं

    GREP_OPTIONS='-v' grep one test.txt

    जो अपेक्षित वापसी करेगा

    line two

    आप इस फॉर्म का उपयोग लॉन्च किए गए प्रोग्राम के इस विशेष उदाहरण के वातावरण को अस्थायी रूप से बदलने के लिए करते हैं।

  3. चर निर्यात करने से चर विरासत में मिलता है:

    export GREP_OPTIONS='-v'
    grep one test.txt

    अब लौटता है

    line two

    शेल में बाद में शुरू की गई प्रक्रियाओं के उपयोग के लिए चर सेट करने का यह सबसे आम तरीका है

  4. यह सब हाशिये में किया गया था। exportबैश बिलिन है; VAR=whateverबैश वाक्य रचना है। envदूसरी ओर, अपने आप में एक कार्यक्रम है। जब envकहा जाता है, निम्नलिखित बातें होती हैं:

    1. आदेश envको एक नई प्रक्रिया के रूप में निष्पादित किया जाता है
    2. env पर्यावरण को संशोधित करता है, और
    3. उस आदेश को कॉल करता है जिसे तर्क के रूप में प्रदान किया गया था। envप्रक्रिया की जगह commandप्रक्रिया।

    उदाहरण:

    env GREP_OPTIONS='-v' grep one test.txt

    यह कमांड दो नई प्रक्रियाएं शुरू करेगी: (i) env और (ii) grep (वास्तव में, दूसरी प्रक्रिया पहले वाले को बदल देगी)। grepप्रक्रिया के दृष्टिकोण से , परिणाम ठीक वैसा ही है जैसा चल रहा है

    GREP_OPTIONS='-v' grep one test.txt

    हालाँकि, आप इस मुहावरे का उपयोग कर सकते हैं यदि आप बैश से बाहर हैं या एक और शेल लॉन्च नहीं करना चाहते हैं (उदाहरण के लिए, जब आप कॉल के exec()बजाय फ़ंक्शंस के परिवार का उपयोग कर रहे हैं system())।

पर अतिरिक्त ध्यान दें #!/usr/bin/env

यही कारण है कि मुहावरे #!/usr/bin/env interpreterका उपयोग इसके बजाय किया जाता है #!/usr/bin/interpreterenvएक कार्यक्रम के लिए एक पूर्ण पथ की आवश्यकता नहीं है, क्योंकि यह execvp()फ़ंक्शन का उपयोग करता है जो PATHचर के माध्यम से खोजता है जैसे शेल करता है, और फिर कमांड रन द्वारा खुद को बदलता है। इस प्रकार, यह पता लगाने के लिए इस्तेमाल किया जा सकता है कि मार्ग पर एक दुभाषिया (जैसे पर्ल या अजगर) "बैठता है"।

इसका यह भी अर्थ है कि वर्तमान पथ को संशोधित करके आप प्रभावित कर सकते हैं कि किस अजगर संस्करण को कहा जाएगा। यह निम्नलिखित संभव बनाता है:

echo -e '#!/usr/bin/bash\n\necho I am an evil interpreter!' > python
chmod a+x ./python
export PATH=.
calibre

कैलिबर को लॉन्च करने के बजाय, परिणाम होगा

I am an evil interpreter!

GREP_OPTIONS = '- v' grep एक test.txt काम क्यों करता है? मुझे लगा कि '-v' के बाद इसे अर्धविराम की जरूरत है (लेकिन मैंने इसकी कोशिश की और यह वास्तव में काम करता है।)
जोकि

2
क्योंकि अर्धविराम के साथ, इसकी व्याख्या दो अलग-अलग बैश कमांड के रूप में की जाती है; पहले एक चर (इसे निर्यात किए बिना) सेट करता है, और दूसरा एक ऐसे वातावरण से शुरू होता है जिसमें चर निर्यात नहीं होता है। अर्धविराम के बिना, हालांकि, यह एक कमांड (grep) है, जो स्थानीय वातावरण सेट करने से पहले है।
जनवरी

envहालांकि सभी चर कहां से आए हैं? मेरा मतलब है कि जब आप एक नया शेल खोलते हैं तो आपके पास हमेशा कुछ चर होते हैं। तो कुछ प्रोग्राम को exportएड करना चाहिए , है ना?
पिथिकोस

1
@Pithikos पर्यावरण चर "एक पर्यावरण की सोर्सिंग" द्वारा निर्धारित किए जाते हैं। डिफ़ॉल्ट रूप से, bash एक सिस्टम-वाइड bashrc (या profile.d या bash_profile) को स्रोत करेगा। फिर यह आपके उपयोगकर्ता को ~ / .bashrc (और / या ~ / .bash_profile) का स्रोत बनाता है। इनमें से किसी भी फ़ाइल में अन्य स्क्रिप्ट्स को स्रोत करने के लिए बैश कमांड हो सकते हैं, ताकि आपके पास अंततः पर्यावरण चर सभी जगह से आ सकें।
एरिक

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