यदि प्रक्रियाओं को माता-पिता के वातावरण विरासत में मिलते हैं, तो हमें निर्यात की आवश्यकता क्यों है?


72

मैंने यहाँ पढ़ा कि exportशेल का उद्देश्य शेल से शुरू की गई उप-प्रक्रियाओं के लिए वैरिएबल को उपलब्ध कराना है।

हालाँकि, मैंने यहाँ और यहाँ भी पढ़ा है कि "प्रक्रियाएँ अपने पर्यावरण को अपने माता-पिता से प्राप्त करती हैं (प्रक्रिया जो उन्हें शुरू हुई)।"

अगर ऐसा है, तो हमें इसकी आवश्यकता क्यों है export? मैं क्या खो रहा हूँ?

क्या शेल चर डिफ़ॉल्ट रूप से पर्यावरण का हिस्सा नहीं हैं? अंतर क्या है?

जवाबों:


74

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

a=1 b=2
export b

वर्तमान शेल में परिणाम यह जानते हुए कि $a1 और $b2 तक फैलता है , लेकिन उपप्रकारों को इसके बारे में कुछ भी नहीं पता होगा aक्योंकि यह पर्यावरण का हिस्सा नहीं है (वर्तमान शेल में भी)।

कुछ उपयोगी उपकरण:

  • set: वर्तमान शेल के मापदंडों को देखने के लिए उपयोगी, निर्यात-या-नहीं
  • set -k: वातावरण में नियत आर्ग सेट करता है। विचार करेंf() { set -k; env; }; f a=1
  • set -a: किसी भी नाम को पर्यावरण में स्थापित करने के लिए शेल को बताता है। जैसे exportहर असाइनमेंट से पहले डालना । .envफाइलों के लिए उपयोगी , जैसा कि अंदर है set -a; . .env; set +a
  • export: पर्यावरण में नाम डालने के लिए खोल को बताता है। निर्यात और असाइनमेंट दो पूरी तरह से अलग-अलग ऑपरेशन हैं।
  • env: एक बाहरी आदेश के रूप में, envआप केवल विरासत में मिले पर्यावरण के बारे में बता सकते हैं, इस प्रकार, यह पवित्रता की जाँच के लिए उपयोगी है।
  • env -i: उपप्रकार शुरू करने से पहले पर्यावरण को साफ करने के लिए उपयोगी।

इसके लिए विकल्प export:

  1. name=val command # कमांड से पहले असाइनमेंट उस नाम को कमांड में एक्सपोर्ट करता है।
  2. declare/local -x name # निर्यात नाम, विशेष रूप से शेल कार्यों में उपयोगी जब आप बाहरी दायरे में नाम उजागर करने से बचना चाहते हैं।
  3. set -a # प्रत्येक असाइनमेंट के बाद निर्यात होता है।

3
set -kऐसा इसलिए है कि एक के स्थान पर उपयोग cmd ENVVAR=valueकिया जा सकता है ENVVAR=value cmd, जो कि आपके उदाहरण में काम नहीं करेगा जब तक कि set -kआह्वान करने से पहले नहीं चलाया गया था f। इसके अलावा, कई गोले आजकल इसका समर्थन नहीं करते हैं और केवल बॉर्न शेल के साथ पिछड़े संगतता के लिए। बॉर्न (या कोर्न) शेल में, जो कार्यों के लिए काम नहीं करेगा। और क्योंकि यह शेल पार्सिंग को प्रभावित करता है, यह उस समय प्रभाव में होता है जब शेल उस कोड को पढ़ता है जो वहां इसका उपयोग करता है।
स्टीफन चेज़लस

1
आप यह भी उल्लेख करना चाह सकते हैंset -a
स्टीफन चेज़ेलस

24

शेल चर और पर्यावरण चर के बीच अंतर है। यदि आप किसी शेल चर को exportआईएनजी के बिना परिभाषित करते हैं, तो इसे प्रक्रियाओं के वातावरण में नहीं जोड़ा जाता है और इस तरह इसके बच्चों को विरासत में नहीं मिलता है।

exportशेल का उपयोग करके आप पर्यावरण को शेल चर जोड़ने के लिए कहते हैं। आप इसका उपयोग करके परीक्षण कर सकते हैं printenv(जो कि इसके वातावरण को प्रिंट करता है stdout, क्योंकि यह एक बाल-प्रक्रिया है जिसे आप exportआईएनजी चर का प्रभाव देखते हैं):

#!/bin/sh

MYVAR="my cool variable"

echo "Without export:"
printenv | grep MYVAR

echo "With export:"
export MYVAR
printenv | grep MYVAR

6

एक चर, एक बार निर्यात किया जाता है, पर्यावरण का हिस्सा है। PATHशेल में ही निर्यात किया जाता है, जबकि कस्टम चर को आवश्यकतानुसार निर्यात किया जा सकता है। कुछ सेटअप कोड का उपयोग करना:

$ cat subshell.sh 
#!/usr/bin/env bash
declare | grep -e '^PATH=' -e '^foo='

तुलना

$ cat test.sh 
#!/usr/bin/env bash
export PATH=/bin
export foo=bar
declare | grep -e '^PATH=' -e '^foo='
./subshell.sh
$ ./test.sh 
PATH=/bin
foo=bar
PATH=/bin
foo=bar

साथ में

$ cat test2.sh 
#!/usr/bin/env bash
PATH=/bin
foo=bar
declare | grep -e '^PATH=' -e '^foo='
./subshell.sh
$ ./test2.sh 
PATH=/bin
foo=bar
PATH=/bin

चूंकि fooशेल द्वारा निर्यात नहीं किया जाता है, और test2.shइसे कभी भी निर्यात नहीं किया जाता है, यह subshell.shअंतिम समय में पर्यावरण का हिस्सा नहीं था ।

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