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


955

किस exportलिए है?

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

export name=value

तथा

name=value

4
तात्कालिक रूप से यह भी ध्यान दें कि export name=valueपोर्टेबल नहीं है। आप जो चाहते हैं उसके आधार पर, name=value; export nameएक पोर्टेबल समाधान के लिए प्रयास करें ।
ट्रिपल

जवाबों:


1054

export उप-प्रक्रियाओं के लिए चर उपलब्ध करता है।

अर्थात्,

export name=value

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

name=value

चर का दायरा शेल तक सीमित है, और किसी अन्य प्रक्रिया के लिए उपलब्ध नहीं है। आप इसे (कहना) लूप वैरिएबल, अस्थायी वैरिएबल आदि के लिए उपयोग करेंगे।

यह ध्यान रखना महत्वपूर्ण है कि एक चर निर्यात करना इसे मूल प्रक्रियाओं के लिए उपलब्ध नहीं कराता है। यह है कि, एक स्पैन्स्ड प्रक्रिया में एक वैरिएबल को निर्दिष्ट और निर्यात करना उस प्रक्रिया में उपलब्ध नहीं है जो इसे लॉन्च किया है।


105
विशेष रूप से निर्यात पर्यावरण के माध्यम से बच्चे की प्रक्रियाओं के लिए चर उपलब्ध कराता है।
बीनो

15
मैं यह भी जोड़ूंगा कि यदि निर्यात एक फ़ाइल में है जिसे आप "स्रोत" (जैसे फ़ाइल नाम) करते हैं तो यह आपके काम के माहौल में भी निर्यात करता है।
रोज़गारपैक

6
@rogerdpack निर्यात के बिना आप ऐसा नहीं कर सकते? cat> blah \ na = hi \ n। blah; गूंज $ ए; मेरे लिए 'हाय' आउटपुट।
डेविड विनीकी

2
अच्छा यह निर्यात के बिना भी काम करता है। इसलिए मुझे लगता है कि किसी फ़ाइल को
सोर्स

19
इसमें एक किनारे का मामला है; उप-प्रक्रिया में चर उपलब्ध name=value command करता है command
ओलिवर चार्ल्सवर्थ

254

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

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

bash-3.2$ 

9
इसके लिए एक और उदाहरणal$ foobar="Whatever" bash
Alun

70

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

संपादित करें (5 साल के परिप्रेक्ष्य के साथ): यह एक मूर्खतापूर्ण जवाब है। 'निर्यात' का उद्देश्य चर को "बाद में निष्पादित आदेशों के वातावरण में" बनाना है, चाहे वे आदेश उप-उपप्रदाय हों या उपप्रकार। एक निष्कपट कार्यान्वयन केवल चर के वातावरण में चर डालना होगा, लेकिन इसे लागू करना असंभव होगा export -p


6
ध्यान दें कि यह पूरी तरह से सच नहीं है। bashवास्तव में , निर्यात वास्तव में वर्तमान शेल के वातावरण में चर को जोड़ता है, लेकिन ऐसा नहीं है dash। यह मुझे लगता है कि वर्तमान शेल के वातावरण में चर जोड़ना सबसे आसान तरीका है जिसे शब्दार्थ को लागू करना है export, लेकिन यह व्यवहार अनिवार्य नहीं है।
विलियम पर्सल जूल

7
मुझे यकीन नहीं है कि dashइसके साथ क्या करना है। मूल पोस्टर के बारे में विशेष रूप से पूछ रहा था bash
स्टारफ़िश

14
प्रश्न को टैग किया गया है bashलेकिन किसी भी बोर्न-शैल संस्करण के लिए समान रूप से लागू होता है। अत्यधिक विशिष्ट होना और केवल उन पर लागू होने वाले उत्तर प्रदान bashकरना एक महान बुराई है।
विलियम पर्ससेल

12
bashशेल का jQuery है।
पर्थका

2
export makes the variable available to subshells, and that is correctयह शब्दावली का बहुत ही भ्रामक उपयोग है। सबस्क्रिप्शन exportको वेरिएबल इनहेरिट करने की आवश्यकता नहीं है । सबप्रोसेस करते हैं।
अमित नायडू

62

यह कहा गया है कि स्पॉन की उप-सीमा होने पर बैश में निर्यात करना आवश्यक नहीं है, जबकि अन्य ने सटीक विपरीत कहा। यह subshells के बीच अंतर नोट करना महत्वपूर्ण है (उन द्वारा बनाई गई हैं कि (), ``, $()या छोरों) और subprocesses (प्रक्रियाओं है कि उदाहरण के लिए नाम से लागू कर रहे हैं, एक शाब्दिक 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:

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

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

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


मैंने कभी ऐसा लूप नहीं देखा है जो (अपने आप में) एक सबशेल बनाया हो; OTOH एक पाइपलाइन करता है (हमेशा पिछले के अलावा टुकड़ों के लिए, कभी-कभी आपके शेल, संस्करण और विकल्पों के आधार पर अंतिम के लिए)। बैकग्राउंडिंग ( &) भी एक सबशेल बनाता है।
dave_thompson_085

इनका क्या var=asdf bash -c 'echo $var'या var=asdf exec bash -c 'echo $var'? आउटपुट है asdf;यदि चर परिभाषा के बाद रखा फर्क नहीं पड़ता। स्पष्टीकरण क्या होगा? ऐसा लगता है कि var(किसी के साथ ;) किसी भी तरह से उपप्रकार के संबंध में है, क्योंकि मूल खोल का इससे कोई लेना-देना नहीं है। echo $varदूसरी लाइन पर निष्पादित होने पर कुछ भी प्रिंट नहीं करता है। लेकिन एक लाइन में खड़ा var=asdf bash -c 'echo $var'; echo $varहै asdf\nasdf
4xy

31

export 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

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


12

export वर्तमान शेल से फोर्क किए गए सभी गोले को उपलब्ध चर बना देगा।


11

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

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

धन्यवाद, यह ठीक वैसी ही जानकारी है जिसकी मैं तलाश कर रहा था क्योंकि मैंने एक स्क्रिप्ट देखी जिसमें पर्यावरण चर का उपयोग किया गया था और फिर उन्हें w / नया मूल्य फिर से "निर्यात" किया गया था, और मैं सोच रहा था कि क्या यह आवश्यक था।
माइक लिपर्ट

8

जैसा कि आप पहले से ही जानते हैं, UNIX प्रक्रियाओं को पर्यावरण चर का एक सेट करने की अनुमति देता है, जो कुंजी / मान जोड़े हैं, दोनों कुंजी और मूल्य तार। ऑपरेटिंग सिस्टम इन जोड़ों को प्रत्येक प्रक्रिया के लिए अलग-अलग रखने के लिए जिम्मेदार है।

कार्यक्रम इस UNIX एपीआई के माध्यम से अपने पर्यावरण चर का उपयोग कर सकते हैं:

  • char *getenv(const char *name);
  • int setenv(const char *name, const char *value, int override);
  • int unsetenv(const char *name);

प्रक्रियाएं मूल प्रक्रियाओं से पर्यावरण चर भी प्राप्त करती हैं। ऑपरेटिंग सिस्टम उस समय सभी "एनवर्स" की एक प्रति बनाने के लिए जिम्मेदार है, जिस समय बच्चे की प्रक्रिया बनाई जाती है।

बैश , अन्य गोले के बीच, उपयोगकर्ता अनुरोध पर अपने पर्यावरण चर को स्थापित करने में सक्षम है। यह वही exportहै जिसके लिए मौजूद है।

exportबैश के लिए पर्यावरण चर सेट करने के लिए एक बैश कमांड है। इस आदेश के साथ सेट किए गए सभी चर, उन सभी प्रक्रियाओं द्वारा विरासत में प्राप्त किए जाएंगे जो यह बैश बनाएंगे।

बैश में पर्यावरण पर अधिक

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

बैश चर को परिभाषित करने के लिए अधिसूचना है name=value। ये चर बैश के अंदर रहते हैं और इनका ऑपरेटिंग सिस्टम द्वारा रखे गए पर्यावरण चर से कोई लेना-देना नहीं है।

शेल पैरामीटर्स पर अधिक (चर सहित)

बैश संदर्भ मैनुअल के अनुसार, यह भी ध्यान देने योग्य है:

शेल पैरामीटर में वर्णित किसी भी साधारण कमांड या फ़ंक्शन के लिए पर्यावरण को पैरामीटर असाइनमेंट के साथ प्रीफ़िक्स करके अस्थायी रूप से संवर्धित किया जा सकता है । ये असाइनमेंट स्टेटमेंट केवल उस कमांड द्वारा देखे गए पर्यावरण को प्रभावित करते हैं।


चीजों को योग करने के लिए:

  • exportऑपरेटिंग सिस्टम में पर्यावरण चर सेट करने के लिए उपयोग किया जाता है। यह वैरिएबल वर्तमान बैश प्रक्रिया द्वारा बनाई गई सभी बाल प्रक्रियाओं के बाद कभी भी उपलब्ध होगा।
  • बैश वैरिएशन नोटेशन (नाम = मान) का उपयोग स्थानीय चर सेट करने के लिए केवल बैश की वर्तमान प्रक्रिया के लिए किया जाता है
  • बैश वैरिएबल नोटेशन किसी अन्य कमांड को प्रीफिक्स करने से केवल उस कमांड के दायरे के लिए पर्यावरण वेरिएबल बनता है।

1
बैश वैर पाइथन के रूप में कई प्रकारों का समर्थन नहीं करता है, लेकिन स्ट्रिंग, पूर्णांक और दो प्रकार के सरणी ('अनुक्रमित' / पारंपरिक और 'साहचर्य' है जो awk सरणी, पर्ल हैश, या पायथॉन तानाशाह के समान है)। अन्य गोले अलग-अलग होते हैं; केवल स्ट्रिंग पोर्टेबल है
dave_thompson_085

7

स्वीकार किए जाते हैं जवाब यह संकेत मिलता है, लेकिन मैं खोल builtins को स्पष्ट संबंध बनाने के लिए करना चाहते हैं:

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

अर्थात्,

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

3

यहाँ अभी तक एक और उदाहरण है:

VARTEST="value of VARTEST" 
#export VARTEST="value of VARTEST" 
sudo env | grep -i vartest 
sudo echo ${SUDO_USER} ${SUDO_UID}:${SUDO_GID} "${VARTEST}" 
sudo bash -c 'echo ${SUDO_USER} ${SUDO_UID}:${SUDO_GID} "${VARTEST}"'  

निर्यात द्वारा केवल VARTEST VARTEST का उपयोग करके sudo bash -c '...' में उपलब्ध है!

आगे के उदाहरणों के लिए देखें:


3

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

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

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


2

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

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

$ MYNAME=Fred
$ export OURNAME=Jim

तब केवल हमारा नाम एनएनवी में दिखाई देता है। चर $ MYNAME env में नहीं है।

$ env | grep NAME
OURNAME=Jim

लेकिन चर $ MYNAME शेल में मौजूद है

$ echo $MYNAME
Fred

1

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


0

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


कृपया बताएं कि आप जो कह रहे हैं वह उत्तर w / उदाहरणों के सीधे विपरीत लगता है।
माइक लिप्टर

यह सही तरीका है यदि आप नहीं चाहते हैं कि चर विश्व स्तर पर निर्यात किए जाएं लेकिन केवल उपप्रकार के लिए उपलब्ध हैं! धन्यवाद।
jtblin
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.