जवाबों:
export
उप-प्रक्रियाओं के लिए चर उपलब्ध करता है।
अर्थात्,
export name=value
इसका मतलब है कि चर नाम उस शेल प्रक्रिया से चलने वाली किसी भी प्रक्रिया के लिए उपलब्ध है । यदि आप इस चर का उपयोग करने के लिए एक प्रक्रिया चाहते हैं export
, तो उस शेल से प्रक्रिया का उपयोग करें , और चलाएं।
name=value
चर का दायरा शेल तक सीमित है, और किसी अन्य प्रक्रिया के लिए उपलब्ध नहीं है। आप इसे (कहना) लूप वैरिएबल, अस्थायी वैरिएबल आदि के लिए उपयोग करेंगे।
यह ध्यान रखना महत्वपूर्ण है कि एक चर निर्यात करना इसे मूल प्रक्रियाओं के लिए उपलब्ध नहीं कराता है। यह है कि, एक स्पैन्स्ड प्रक्रिया में एक वैरिएबल को निर्दिष्ट और निर्यात करना उस प्रक्रिया में उपलब्ध नहीं है जो इसे लॉन्च किया है।
name=value command
करता है command
।
दूसरों ने उत्तर दिया कि निर्यात चर को उप-भागों में उपलब्ध कराता है, और यह सही है लेकिन केवल एक पक्ष प्रभाव है। जब आप एक चर निर्यात करते हैं, तो यह उस चर को वर्तमान शेल (यानी शेल कॉल putenv(3)
या setenv(3)
) के वातावरण में डालता है ।
एक प्रक्रिया का वातावरण निष्पादन के दौरान विरासत में मिला है, जिससे उप-श्रेणियों में चर दिखाई दे रहा है।
संपादित करें (5 साल के परिप्रेक्ष्य के साथ): यह एक मूर्खतापूर्ण जवाब है। 'निर्यात' का उद्देश्य चर को "बाद में निष्पादित आदेशों के वातावरण में" बनाना है, चाहे वे आदेश उप-उपप्रदाय हों या उपप्रकार। एक निष्कपट कार्यान्वयन केवल चर के वातावरण में चर डालना होगा, लेकिन इसे लागू करना असंभव होगा export -p
।
bash
वास्तव में , निर्यात वास्तव में वर्तमान शेल के वातावरण में चर को जोड़ता है, लेकिन ऐसा नहीं है dash
। यह मुझे लगता है कि वर्तमान शेल के वातावरण में चर जोड़ना सबसे आसान तरीका है जिसे शब्दार्थ को लागू करना है export
, लेकिन यह व्यवहार अनिवार्य नहीं है।
dash
इसके साथ क्या करना है। मूल पोस्टर के बारे में विशेष रूप से पूछ रहा था bash
।
bash
लेकिन किसी भी बोर्न-शैल संस्करण के लिए समान रूप से लागू होता है। अत्यधिक विशिष्ट होना और केवल उन पर लागू होने वाले उत्तर प्रदान bash
करना एक महान बुराई है।
bash
शेल का jQuery है।
export makes the variable available to subshells, and that is correct
यह शब्दावली का बहुत ही भ्रामक उपयोग है। सबस्क्रिप्शन export
को वेरिएबल इनहेरिट करने की आवश्यकता नहीं है । सबप्रोसेस करते हैं।
यह कहा गया है कि स्पॉन की उप-सीमा होने पर बैश में निर्यात करना आवश्यक नहीं है, जबकि अन्य ने सटीक विपरीत कहा। यह 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
कमांड से बदल दिया है , इसलिए उस कमांड को निष्पादित करने के लिए कुछ भी नहीं बचा है।
&
) भी एक सबशेल बनाता है।
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
।
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
तो, अब यह उतना ही स्पष्ट होना चाहिए जितना कि गर्मी का सूरज! ब्रेन अग्न्यू, एलेक्सप और विलियम प्रुसेल का धन्यवाद।
यह ध्यान दिया जाना चाहिए कि आप एक चर निर्यात कर सकते हैं और बाद में मूल्य बदल सकते हैं। परिवर्तनशील मूल्य बाल प्रक्रियाओं के लिए उपलब्ध होगा। एक बार निर्यात एक चर के लिए निर्धारित किया गया है जो आपको export -n <var>
संपत्ति को हटाने के लिए करना चाहिए ।
$ K=1
$ export K
$ K=2
$ bash -c 'echo ${K-unset}'
2
$ export -n K
$ bash -c 'echo ${K-unset}'
unset
जैसा कि आप पहले से ही जानते हैं, 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
ऑपरेटिंग सिस्टम में पर्यावरण चर सेट करने के लिए उपयोग किया जाता है। यह वैरिएबल वर्तमान बैश प्रक्रिया द्वारा बनाई गई सभी बाल प्रक्रियाओं के बाद कभी भी उपलब्ध होगा।स्वीकार किए जाते हैं जवाब यह संकेत मिलता है, लेकिन मैं खोल 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
यहाँ अभी तक एक और उदाहरण है:
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 '...' में उपलब्ध है!
आगे के उदाहरणों के लिए देखें:
bash-hackers.org/wiki/doku.php/scripting/processtree
यूनिक्स के दो रचनाकारों, ब्रायन कर्निघन और रॉब पाइक ने अपनी पुस्तक "द यूनिक्स प्रोग्रामिंग पर्यावरण" में इसकी व्याख्या की है। शीर्षक के लिए Google और आपको आसानी से एक पीडीएफ संस्करण मिलेगा।
वे खंड 3.6 में शेल चर को संबोधित करते हैं, और export
उस खंड के अंत में कमांड के उपयोग पर ध्यान केंद्रित करते हैं :
जब आप उप-गोले में एक चर के मूल्य को सुलभ बनाना चाहते हैं, तो शेल के निर्यात कमांड का उपयोग किया जाना चाहिए। (आप सोच सकते हैं कि एक उप-शेल से अपने माता-पिता के लिए चर का मूल्य निर्यात करने का कोई तरीका क्यों नहीं है)।
पर्यावरण में निर्यात किए जा रहे चर (env) और पर्यावरण में नहीं होने वाले गैर-निर्यातित चर के बीच का अंतर दिखाने के लिए:
अगर मैं ऐसा करता हूं:
$ MYNAME=Fred
$ export OURNAME=Jim
तब केवल हमारा नाम एनएनवी में दिखाई देता है। चर $ MYNAME env में नहीं है।
$ env | grep NAME
OURNAME=Jim
लेकिन चर $ MYNAME शेल में मौजूद है
$ echo $MYNAME
Fred
यद्यपि चर्चा में स्पष्ट रूप से उल्लेख नहीं किया गया है, लेकिन निर्यात के उपयोग के लिए आवश्यक नहीं है जब सभी प्रकारों को बच्चे की प्रक्रिया में कॉपी किए जाने के बाद से अंदर से एक सबशेल पैदा हो।
export name=value
पोर्टेबल नहीं है। आप जो चाहते हैं उसके आधार पर,name=value; export name
एक पोर्टेबल समाधान के लिए प्रयास करें ।