अगर मैं चला
export TEST=foo
echo $TEST
यह फू का उत्पादन करता है।
अगर मैं चला
TEST=foo echo $TEST
ऐसा नहीं होता। मैं निर्यात या स्क्रिप्ट का उपयोग किए बिना यह कार्यक्षमता कैसे प्राप्त कर सकता हूं?
अगर मैं चला
export TEST=foo
echo $TEST
यह फू का उत्पादन करता है।
अगर मैं चला
TEST=foo echo $TEST
ऐसा नहीं होता। मैं निर्यात या स्क्रिप्ट का उपयोग किए बिना यह कार्यक्षमता कैसे प्राप्त कर सकता हूं?
जवाबों:
ऐसा इसलिए है क्योंकि शेल कमांड लाइन में चर का विस्तार करता है इससे पहले कि वह वास्तव में कमांड चलाता है और उस समय चर मौजूद नहीं है। यदि तुम प्रयोग करते हो
TEST=foo; echo $TEST
यह काम करेगा।
export
चर को बाद में निष्पादित आदेशों के वातावरण में दिखाई देगा (यह कैसे काम करता है इस पर देखें help export
)। यदि आपको केवल एक कमांड के वातावरण में चर की आवश्यकता है, तो आपने जो प्रयास किया है, उसका उपयोग करें:
TEST=foo your-application
$TEST
कमांड लाइन निष्पादित होने से पहले शेल का विस्तार होता है। एक बार echo
चल रहा है (यह भी ध्यान दें कि echo
आमतौर पर शेल में अंतर्निहित कमांड में अनुवाद होगा और नहीं /bin/echo
) यह अपने वातावरण में चर सेट को देखता है। हालांकि, इसके वातावरण से चर की सामग्री का उत्पादन करने के लिए echo $TEST
नहीं कहता है। यह शेल को तर्क के साथ चलने के लिए कहता है जो वर्तमान में चर में है - और वे दो बहुत अलग चीजें हैं। echo
TEST
echo
TEST
var=value sh -c 'echo "$var"'
?
"… $var …"
) के अंदर विस्तारित किया जाता है, लेकिन एकल उद्धरणों (जैसे, '… $var …'
) के अंदर नहीं । चूंकि echo "$var"
सिंगल कोट्स के अंदर है, इसलिए पूरे स्ट्रिंग sh -c
को बाहरी, इंटरेक्टिव शेल द्वारा व्याख्या किए बिना नए ( ) शेल में पास किया जाता है । … (Cont'd)
sh -c
) चाइल्ड शेल द्वारा किया जाता है।
मुझे संदेह है कि आप पर्यावरण चर की बजाय एक सीमित दायरे के लिए शेल चर रखना चाहते हैं । पर्यावरण चर, कमांड के लिए पारित तार की एक सूची है जब उन्हें निष्पादित किया जाता है ।
में
var=value echo whatever
आप var=value
स्ट्रिंग को उस वातावरण में पास कर रहे हैं जो गूंज प्राप्त करता है। हालाँकि, echo
अपनी पर्यावरण सूची के साथ कुछ भी नहीं करता है और वैसे भी अधिकांश गोले echo
में बनाया जाता है और इसलिए इसे निष्पादित नहीं किया जाता है ।
अगर आपने लिखा होता
var=value sh -c 'echo "$var"'
यह एक और मामला होता। यहाँ, हम गुजर रहे हैं var=value
करने के लिए sh
आदेश, और sh
अपने पर्यावरण के उपयोग करने के लिए होता है। गोले अपने वातावरण से प्राप्त होने वाले प्रत्येक चर को शेल चर में परिवर्तित करते हैं, इसलिए var
पर्यावरण चर sh
प्राप्त करने वाले को एक $var
चर में परिवर्तित किया जाएगा , और जब यह उस echo
कमांड लाइन में फैलता है, तो यह बन जाएगा echo value
। क्योंकि पर्यावरण डिफ़ॉल्ट रूप से विरासत में मिला है, इसके वातावरण में echo
भी प्राप्त var=value
होगा (या यदि इसे निष्पादित किया गया था), लेकिन फिर से, echo
पर्यावरण के बारे में परवाह नहीं करता है।
अब, यदि मुझे संदेह है, तो आप जो चाहते हैं वह शेल चरों के दायरे को सीमित करना है, कई संभावित दृष्टिकोण हैं।
आंशिक रूप से (Bourne और POSIX):
(var=value; echo "1: $var"); echo "2: $var"
ऊपर (...) एक उप-शेल (अधिकांश शेल में एक नई शेल प्रक्रिया) शुरू करता है, इसलिए वहां घोषित कोई भी वेरिएबल केवल उस उप-शेल को प्रभावित करेगा, इसलिए मुझे उपरोक्त कोड "1: मान" की उम्मीद होगी और "2:" या "2: जो भी- var-was-set-to-before" था।
अधिकांश बॉर्न-जैसे गोले के साथ, आप फ़ंक्शंस और "स्थानीय" बिलिन का उपयोग कर सकते हैं:
f() {
local var
var=value
echo "1: $var"
}
f
echo "2: $var"
Zsh के साथ, आप इनलाइन फ़ंक्शन का उपयोग कर सकते हैं:
(){ local var=value; echo "1: $var"; }; echo "2: $var"
या:
function { local var=value; echo "1: $var"; }; echo "2: $var"
बैश और zsh के साथ (लेकिन राख, pdksh या AT & T ksh नहीं), यह ट्रिक भी काम करती है:
var=value eval 'echo "1: $var"'; echo "2: $var"
एक संस्करण है कि कुछ और गोले में काम करता है ( dash
, mksh
, yash
), लेकिन नहीं zsh
(जब तक में sh
/ ksh
अनुकरण):
var=value command eval 'echo "1: $var"'; echo "2: $var"
( POSIX गोले में command
एक विशेष बिलिन (यहाँ eval
) के सामने उपयोग करने से उनकी ख़ासियत दूर हो जाती है (यहाँ से वे चर असाइनमेंट वापस आने के बाद प्रभाव में रहते हैं)
आप इसे सही तरीके से कर रहे हैं, लेकिन बैश सिंटैक्स गलत व्याख्या करना आसान है: आप सोच सकते हैं कि env var लाने का echo $TEST
कारण बनता echo
है TEST
तब इसे प्रिंट करें, ऐसा नहीं है। तो दिया
export TEST=123
फिर
TEST=456 echo $TEST
निम्नलिखित अनुक्रम शामिल है:
शेल पूरी कमांड लाइन को पार्स करता है और सभी वैरिएबल सबस्टेशनों को निष्पादित करता है, इसलिए कमांड लाइन बन जाती है
TEST=456 echo 123
यह कमांड के पहले टेम्प वर्सेस बनाता है, इसलिए यह TEST
456 के साथ वर्तमान मूल्य को बचाता है और इसे अधिलेखित करता है; कमांड लाइन अब है
echo 123
यह शेष कमांड को निष्पादित करता है, जो इस मामले में 123 को stdout में प्रिंट करता है (इसलिए शेल कमांड जो अवशेष भी मंदिर के मूल्य का उपयोग नहीं करता है TEST
)
यह के मूल्य को पुनर्स्थापित करता है TEST
इसके बजाय प्रिंटेनव का उपयोग करें, क्योंकि इसमें चर प्रतिस्थापन शामिल नहीं है:
>> export TEST=123
>> printenv TEST
123
>> TEST=456 printenv TEST
456
>> printenv TEST && TEST=456 printenv TEST && TEST=789 printenv TEST && printenv TEST
123
456
789
123
>>
printenv
अवधारणा के परीक्षण / प्रमाण के लिए सहायक पाया (एक स्क्रिप्ट जैसा व्यवहार करता है, जैसा कि विरोध किया जाता है echo
)
आप इसका उपयोग करके काम कर सकते हैं:
TEST=foo && echo $TEST
TEST=foo
एक अलग बयान के रूप में चल रहा है - यह केवल के संदर्भ में निर्धारित नहीं है echo
।