linux - निर्यात के साथ या बिना एक चर परिभाषित करना




bash shell (10)

के लिए export क्या है?

के बीच क्या अंतर है:

export name=value

तथा

name=value

अन्य ने जवाब दिया है कि निर्यात चरम पर उपलब्ध चर बनाता है, और यह सही है लेकिन केवल एक दुष्प्रभाव है। जब आप एक चर निर्यात करते हैं, तो यह उस चर को वर्तमान खोल के वातावरण में रखता है (यानी खोल कॉल Putenv (3) या setenv (3))। किसी प्रक्रिया का वातावरण निष्पादन में विरासत में मिलता है, जिससे चरम पर चर दिखाई देता है।


ऐसा कहा गया है कि सब्सक्रिप्शन के दौरान बाश में निर्यात करना जरूरी नहीं है, जबकि अन्य ने बिल्कुल विपरीत कहा है। सबहेल्स (जो कि () , `` , $() या लूप द्वारा बनाए गए () और नाम से लागू की जाने वाली प्रक्रियाओं), उदाहरण के लिए आपकी लिपि में दिखाई देने वाली शाब्दिक bash बीच अंतर को ध्यान में रखना महत्वपूर्ण है। सब्सक्रिप्ल्स को उनके निर्यात किए गए राज्य के बावजूद माता-पिता से सभी चरों तक पहुंच होगी । दूसरी ओर उपप्रजाय केवल निर्यात किए गए चर देखेंगे। इन दो संरचनाओं में आम बात यह है कि न तो चरम खोल में वैरिएबल पास कर सकते हैं।

$ noexport=noexport; export export=export; (echo subshell: $noexport $export; subshell=subshell); bash -c 'echo subprocess: $noexport $export; subprocess=subprocess'; echo parent: $subshell $subprocess
subshell: noexport export
subprocess: export
parent:

भ्रम का एक और स्रोत है: कुछ सोचते हैं कि 'फोर्कड' उपप्रोसेसेस वे हैं जो गैर-निर्यात किए गए चर नहीं देखते हैं। आम तौर पर फोर्क () एस को तुरंत () एस द्वारा पीछा किया जाता है, और यही कारण है कि ऐसा लगता है कि कांटा () की तलाश है, जबकि वास्तव में यह exec () है। आप exec कमांड के साथ पहले फोर्क () आईएनजी के बिना कमांड चला सकते हैं, और इस विधि से शुरू की गई प्रक्रियाओं के पास अप्रत्याशित चरों तक पहुंच नहीं होगी:

$ noexport=noexport; export export=export; exec bash -c 'echo execd process: $noexport $export; execd=execd'; echo parent: $execd
execd process: export

ध्यान दें कि हम इस समय parent: नहीं देखते हैं parent: क्योंकि हमने पैरेंट खोल को exec कमांड से बदल दिया है, इसलिए उस आदेश को निष्पादित करने के लिए कुछ भी नहीं बचा है।


डिफ़ॉल्ट रूप से, एक स्क्रिप्ट के भीतर बनाए गए चर केवल वर्तमान खोल के लिए उपलब्ध होते हैं; बाल प्रक्रियाओं (उप-शैल) को उन मानों तक पहुंच नहीं होगी जिन्हें सेट या संशोधित किया गया है। मूल्यों को देखने के लिए बाल प्रक्रियाओं को अनुमति देना, निर्यात कमांड के उपयोग की आवश्यकता है।


पर्यावरण में एक निर्यातित चर के बीच अंतर दिखाने के लिए (एनवी) और एक गैर-निर्यातित चर पर्यावरण में नहीं है:

अगर मैं ऐसा करता हूं:

$ MYNAME=Fred
$ export OURNAME=Jim

तो env में केवल $ OURNAME दिखाई देता है। परिवर्तनीय $ MYNAME env में नहीं है।

$ env | grep NAME
OURNAME=Jim

लेकिन परिवर्तनीय $ MYNAME खोल में मौजूद है

$ echo $MYNAME
Fred

यह ध्यान दिया जाना चाहिए कि आप एक चर निर्यात कर सकते हैं और बाद में मूल्य बदल सकते हैं। परिवर्तनीय का बदला मूल्य बाल प्रक्रियाओं के लिए उपलब्ध होगा। एक बार एक चर के लिए निर्यात सेट किया गया है, तो आपको संपत्ति को हटाने के लिए export -n <var> करना होगा।

$ K=1
$ export K
$ K=2
$ bash -c 'echo ${K-unset}'
2
$ export -n K
$ bash -c 'echo ${K-unset}'
unset

यह बताने के लिए कि अन्य उत्तर क्या कह रहे हैं:

al$ foo="Hello, World"
al$ echo $foo
Hello, World
al$ bar="Goodbye"
al$ export foo
al$ bash
bash-3.2$ echo $foo
Hello, World
bash-3.2$ echo $bar

bash-3.2$ 

यूनिक्स, ब्रायन कर्निघान और रोब पाइक के दो रचनाकारों ने अपनी पुस्तक "द यूनिक्स प्रोग्रामिंग एनवायरनमेंट" में इसकी व्याख्या की। शीर्षक के लिए Google और आपको आसानी से एक पीडीएफ संस्करण मिल जाएगा।

वे अनुभाग 3.6 में खोल चर को संबोधित करते हैं, और उस खंड के अंत में export आदेश के उपयोग पर ध्यान केंद्रित करते हैं:

जब आप सब-शैल में पहुंच योग्य चर का मान बनाना चाहते हैं, तो खोल के निर्यात कमांड का उपयोग किया जाना चाहिए। (आप इस बारे में सोच सकते हैं कि एक उप-खोल से अपने माता-पिता को एक चर के मान को निर्यात करने का कोई तरीका क्यों नहीं है)।


export NAME=value और चर के लिए export NAME=value जो उपप्रोसेसर का अर्थ है।

NAME=value अस्थायी या लूप चर के लिए NAME=value वर्तमान खोल प्रक्रिया के लिए निजी है।

अधिक विस्तार से, export पर्यावरण में परिवर्तनीय नाम को चिह्नित करता है जो सृजन पर उपप्रोसेसरों और उनके उपप्रोसेसरों की प्रतिलिपि बनाता है। उपप्रोसेसर से कभी भी कोई नाम या मूल्य कॉपी नहीं किया जाता है।

  • एक समान त्रुटि बराबर चिह्न के चारों ओर एक जगह जगह है:

    $ export FOO = "bar"  
    bash: export: `=': not a valid identifier
    
  • केवल निर्यातित चर ( B ) उपप्रोसेसर द्वारा देखा जाता है:

    $ A="Alice"; export B="Bob"; echo "echo A is \$A. B is \$B" | bash
    A is . B is Bob
    
  • उपप्रोसेस में परिवर्तन मुख्य खोल नहीं बदलते हैं:

    $ export B="Bob"; echo 'B="Banana"' | bash; echo $B
    Bob
    
  • निर्यात के लिए चिह्नित वैरिएबल में उपप्रोसेस बनने पर मूल्यों की प्रतिलिपि बनाई गई है:

    $ export B="Bob"; echo '(sleep 30; echo "Subprocess 1 has B=$B")' | bash &
    [1] 3306
    $ B="Banana"; echo '(sleep 30; echo "Subprocess 2 has B=$B")' | bash 
    Subprocess 1 has B=Bob
    Subprocess 2 has B=Banana
    [1]+  Done         echo '(sleep 30; echo "Subprocess 1 has B=$B")' | bash
    
  • केवल निर्यात किए गए चर पर्यावरण ( man environ ) का हिस्सा बन जाते हैं:

     $ ALICE="Alice"; export BOB="Bob"; env | grep "ALICE\|BOB"
     BOB=Bob
    

तो, अब यह गर्मी के सूरज की तरह स्पष्ट होना चाहिए! ब्रेन एग्नेव, एलेक्स, और विलियम प्रसेल के लिए धन्यवाद।


export मौजूदा शैल से फोर्क किए गए सभी गोले में परिवर्तनीय उपलब्ध कराएगा।


स्वीकार्य उत्तर इसका तात्पर्य है, लेकिन मैं शैल बिल्टिन से कनेक्शन स्पष्ट करना चाहता हूं:

जैसा कि पहले से उल्लेख किया गया है, export शैल और बच्चों दोनों के लिए एक चर उपलब्ध कराएगा। यदि export का उपयोग नहीं किया जाता है, तो चर केवल शैल में उपलब्ध होगा, और केवल शैल बिल्टिन ही इसका उपयोग कर सकते हैं।

अर्थात्,

tango=3
env | grep tango # prints nothing, since env is a child process
set | grep tango # prints tango=3 - "type set" shows `set` is a shell builtin




shell