क्या कोष्ठक वास्तव में एक उपधारा में कमांड डालते हैं?


94

मैंने जो पढ़ा है, उसमें कोष्ठक में एक कमांड डालकर उसे एक स्क्रिप्ट चलाने के समान, उप-भाग में चलाना चाहिए। यदि यह सत्य है, तो x निर्यात नहीं होने पर चर x को कैसे देखता है?

x=1

(echo $x)कमांड लाइन पर चलने से परिणाम 1 हो जाता है

चल रहा है echo $xकुछ भी नहीं में एक स्क्रिप्ट परिणामों में, के रूप में उम्मीद

जवाबों:


134

मूल शेल प्रक्रिया की लगभग समान प्रतिलिपि के रूप में एक सबशेल शुरू होता है। हुड के तहत, शेल forkसिस्टम कॉल 1 को कॉल करता है , जो एक नई प्रक्रिया बनाता है जिसका कोड और मेमोरी 2 प्रतियां हैं । जब उप-संस्करण बनाया जाता है, तो इसके और इसके माता-पिता के बीच बहुत कम अंतर होते हैं। विशेष रूप से, उनके पास एक ही चर हैं। यहां तक ​​कि $$विशेष चर उप मानों में समान मूल्य रखता है: यह मूल शेल की प्रक्रिया आईडी है। इसी तरह $PPIDमूल खोल के माता-पिता का पीआईडी ​​है।

कुछ गोले उप-प्रकार में कुछ चर बदलते हैं। बैश BASHPIDशेल प्रक्रिया के पीआईडी ​​पर सेट हो जाता है, जो उप-श्रेणियों में बदल जाता है। बैश, zsh और mksh $RANDOMमाता पिता और उपधारा में विभिन्न मूल्यों की उपज के लिए व्यवस्था करते हैं । लेकिन इन जैसे विशेष मामलों में अंतर्निहित के अलावा, सभी चर का मूल शेल में समान मान है, समान निर्यात स्थिति, समान रीड-ओनली स्थिति, आदि सभी फ़ंक्शन परिभाषाएँ, अन्य नाम परिभाषाएँ, शैल विकल्प और अन्य सेटिंग्स भी विरासत में मिली हैं।

इसके द्वारा बनाई गई उपधारा (…)में इसके निर्माता के रूप में एक ही फ़ाइल वर्णनकर्ता है। उपधारा बनाने के कुछ अन्य साधन उपयोगकर्ता कोड को निष्पादित करने से पहले कुछ फ़ाइल विवरणों को संशोधित करते हैं; उदाहरण के लिए, पाइप का बायाँ भाग, उप-भाग 3 में चलता है, जो पाइप से जुड़े मानक आउटपुट के साथ है। उपधारा भी एक ही वर्तमान निर्देशिका, एक ही संकेत मुखौटा, आदि के साथ शुरू होता है। कुछ अपवादों में से एक यह है कि उपधाराएँ कस्टम जाल को प्राप्त नहीं करती हैं: उपेक्षित संकेतों ( ) को उपधारा में अनदेखा किया जाता है, लेकिन अन्य जाल ( संकेत ) रीसेट हो जाते हैं डिफ़ॉल्ट कार्रवाई के लिए 4trap '' SIGNALtrap CODE

एक उपधारा इस प्रकार एक स्क्रिप्ट को निष्पादित करने से अलग है। एक स्क्रिप्ट एक अलग कार्यक्रम है। यह अलग-अलग कार्यक्रम संयोग से एक स्क्रिप्ट भी हो सकता है जिसे माता-पिता के समान दुभाषिया द्वारा निष्पादित किया जाता है, लेकिन यह संयोग अलग कार्यक्रम को माता-पिता के आंतरिक डेटा पर कोई विशेष दृश्यता नहीं देता है। गैर-निर्यात किए गए चर आंतरिक डेटा होते हैं, इसलिए जब चाइल्ड शेल स्क्रिप्ट के लिए दुभाषिया निष्पादित किया जाता है , तो यह इन चर को नहीं देखता है। निर्यात किए गए चर, यानी पर्यावरण चर, निष्पादित कार्यक्रमों में प्रेषित किए जाते हैं।

इस प्रकार:

x=1
(echo $x)

प्रिंट करता है, 1क्योंकि उपधारा उस खोल की प्रतिकृति है जिसने इसे बनाया है।

x=1
sh -c 'echo $x'

एक शेल के एक बच्चे की प्रक्रिया के रूप में एक शेल को चलाने के लिए होता है, लेकिन xदूसरी लाइन पर दूसरी लाइन के साथ अधिक कनेक्शन नहीं xहोता है

x=1
perl -le 'print $x'

या

x=1
python -c 'print x'

1 एक अपवाद ksh93शेल है जहां फोर्किंग को अनुकूलित किया गया है और इसके अधिकांश साइड इफेक्ट का अनुकरण किया गया है।
2 शब्दार्थ, वे प्रतियां हैं। कार्यान्वयन के दृष्टिकोण से, बहुत कुछ साझा हो रहा है।
3 दाहिने हाथ की ओर, यह शेल पर निर्भर करता है।
4 यदि आप इसका परीक्षण करते हैं, तो ध्यान दें कि जैसी चीजें$(trap) मूल शेल के जाल की रिपोर्ट कर सकती हैं। यह भी ध्यान दें कि कई खोलों में जाल वाले मामलों में कोने के कीड़े हैं। उदाहरण के लिए निंजाल नोटों का कहना है कि 4.3 के रूप में, "दो उपधारा" मामले में नेस्टेड सब-ट्रैल से जाल bash -x -c 'trap "echo ERR at \$BASH_SUBSHELL \$BASHPID" ERR; set -E; false; echo one subshell; (false); echo two subshells; ( (false) )'चलाता है ERR, लेकिन ERRमध्यवर्ती उपधारा से जाल नहीं - set -Eविकल्प को प्रचारित करना चाहिएERRसभी उपधाराओं के लिए जाल लेकिन मध्यवर्ती उपधारा दूर अनुकूलित है और इसलिए इसके ERRजाल को चलाने के लिए नहीं है ।


2
@ कुसलानंद नं। ( x=out; (x=in; echo $x))
गिल्स

2
@ flow2k यह उसी स्तर पर होने वाली चीजों के विस्तार का क्रम है। लेकिन आपको यह भी विचार करने की आवश्यकता है कि मूल्यांकन के साथ विस्तार कैसे मिलाया जाता है। जब विस्तार के लिए एक नेस्टेड निर्माण के मूल्यांकन की आवश्यकता होती है, तो आंतरिक निर्माण का मूल्यांकन पहले किया जाता है। इसलिए, उदाहरण के लिए, मूल्यांकन करने के लिए echo $(x=2; echo $x), टुकड़े $(x=2; echo $x)को विस्तारित करने की आवश्यकता है। इसके लिए कमांड का मूल्यांकन करना आवश्यक है x=2; echo $x$xइस मूल्यांकन के दौरान होता है का विस्तार , भाग का मूल्यांकन करने के बाद x=2
गाइल्स

2
@ flow2k पैरामीटर विस्तार और कमांड प्रतिस्थापन के बीच कोई आदेश नहीं है। ध्यान दें कि यह वाक्य अर्धविराम का उपयोग विस्तार चरणों को अलग करने के लिए करता है, लेकिन पैरामीटर विस्तार और कमांड प्रतिस्थापन एक ही अर्धविराम-सीमांकित खंड (हां, यह सूक्ष्म है) में हैं। आदेश तब मायने रखता है जब भागों में से एक का साइड इफेक्ट होता है जो दूसरे भाग को प्रभावित करता है, उदाहरण के लिए ( xपरेशान) echo $(echo foo >somefile)${x-$(cat somefile)}या echo $(echo $x),${x=1}
गाइल्स

1
@Gilles; मैं उलझन में हूं। यदि कोई सबस्क्रिप्शन किसी स्क्रिप्ट को निष्पादित करने से अलग है, तो ऐसा क्यों कहा जाता है: शेल स्क्रिप्ट को चलाना एक नई प्रक्रिया, एक सब-टाइम लॉन्च करता है। ? इसके अलावा, शेल वातावरण के डुप्लिकेट के रूप में एक सबस्क्रिप्शन वातावरण बनाया जाएगा । इसलिए ,/file को सब-इनहेल्ड वातावरण में निष्पादित किया जाएगा और इस प्रकार इसे शेल असाइनमेंट को इनहेरिट करना चाहिए जो कि चर असाइनमेंट द्वारा सेट किए गए हैं।
haccks

2
@haccks ABS में परिभाषा एक सन्निकटन है, और बहुत अच्छा नहीं है। उदाहरण अच्छे हैं, लेकिन उस पृष्ठ की पहली दो पंक्तियाँ इतनी अधिक हैं कि वे गलत हैं। एक स्क्रिप्ट को दूसरी स्क्रिप्ट से चलाने से एक नई प्रक्रिया शुरू होती है , जो सबस्क्रिप्शन नहीं है। SUS में, परिभाषाएँ सही हैं (लेकिन हमेशा समझने में बहुत आसान नहीं)। ./fileएक उपधारा में निष्पादित नहीं किया जाता है। यह भी देखें unix.stackexchange.com/q/261638 और unix.stackexchange.com/a/157962
Gilles

15

जाहिर है, हां, जैसा कि सभी दस्तावेज कहते हैं, एक उप-आधार में एक कोष्ठक कमांड चलाया जाता है।

उपधारा सभी माता-पिता के चर की एक प्रति विरासत में मिलती है। अंतर यह है कि आपके द्वारा उपधारा में किए गए कोई भी परिवर्तन भी माता-पिता में नहीं किए गए हैं।

Ksh मैन पेज इसे बाश के मुकाबले थोड़ा साफ करता है:

man ksh:

गैर-निर्यात किए गए चर को हटाए बिना एक उप-शेल में एक कोष्ठक कमांड निष्पादित किया जाता है।

man bash:

(सूची)

सूची को एक सबहेल्ड वातावरण में निष्पादित किया जाता है (नीचे COMMAND EXECUTION ENVIRONMENT देखें)। वैरिएबल असाइनमेंट और बिल्डइन कमांड जो शेल के वातावरण को प्रभावित करते हैं कमांड के पूरा होने के बाद प्रभाव में नहीं रहते हैं।

कॉमंड एक्जामिनेशन एनवायरनमेंट

शेल में एक निष्पादन वातावरण होता है, जिसमें निम्न शामिल होते हैं: [...] शेल पैरामीटर जो चर असाइनमेंट [...] द्वारा निर्धारित होते हैं।
कमांड प्रतिस्थापन, कोष्ठक के साथ समूहीकृत कमांड, और एसिंक्रोनस कमांड को एक उप-वातावरण में लागू किया जाता है जो शेल पर्यावरण का एक डुप्लिकेट है, [...]


3
यह इसके विपरीत है When a simple command other than a builtin or shell function is to be executed, it is invoked in a separate execution environment that consists of the following., जिसमें आइटम शामिल है: · shell variables and functions marked for export, along with variables exported for the command, passed in the environment(उसी man bashअनुभाग से) जो बताता है कि क्यों echo $x-स्क्रिप्ट xनिर्यात नहीं होने पर कुछ भी प्रिंट करता है।
जोहान ई
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.