POSIX शब्दावली में, एक सबहेल वातावरण शैल निष्पादन वातावरण की धारणा से जुड़ा हुआ है ।
एक सबशेल पर्यावरण एक अलग शैल निष्पादन वातावरण है जिसे मूल वातावरण के डुप्लिकेट के रूप में बनाया गया है। उस निष्पादन परिवेश में खोली गई फ़ाइलें, umask, कार्यशील निर्देशिका, शेल चर / फ़ंक्शन / उपनाम जैसी चीजें शामिल हैं ...
उस सबस्क्रिप्शन वातावरण में परिवर्तन मूल वातावरण को प्रभावित नहीं करता है।
परंपरागत रूप से बॉर्न शेल या ksh88 में, जिस पर POSIX स्पेसिफिकेशन आधारित है, जो एक चाइल्ड प्रोसेस को फोर्क करके किया गया था।
उन क्षेत्रों में जहां POSIX की आवश्यकता होती है या एक उप-वातावरण में चलने की आज्ञा देता है, वे हैं जहां पारंपरिक रूप से ksh88 ने एक बच्चे के खोल प्रक्रिया को कांटा।
हालाँकि यह कार्यान्वयन को उसके लिए एक बाल प्रक्रिया का उपयोग करने के लिए मजबूर नहीं करता है।
एक शेल किसी भी तरह से उस अलग निष्पादन वातावरण को लागू करने के बजाय चुन सकता है।
उदाहरण के लिए, ksh93 माता-पिता के निष्पादन वातावरण की विशेषताओं को सहेजकर और संदर्भों में उप-स्तरीय वातावरण को समाप्त करने पर उन्हें पुनर्स्थापित करता है, जहां फोर्किंग से बचा जा सकता है (फोर्किंग के रूप में एक अनुकूलन अधिकांश प्रणालियों पर काफी महंगा है)।
उदाहरण के लिए, इसमें:
cd /foo; pwd
(cd /bar; pwd)
pwd
POSIX को cd /foo
अलग वातावरण में चलाने की आवश्यकता होती है और वह कुछ इस तरह आउटपुट करता है:
/foo
/bar
/foo
इसे अलग प्रक्रिया में चलाने की आवश्यकता नहीं है। उदाहरण के लिए, यदि स्टडआउट एक टूटी हुई पाइप बन जाती है, pwd
तो सब-वेल वातावरण में चलाए जाने वाले SIGPIPE को केवल और केवल शेल प्रक्रिया में भेजा जा सकता है।
सहित अधिकांश गोले एक बच्चे की प्रक्रिया में bash
कोड का मूल्यांकन करके इसे लागू करेंगे (...)
(जबकि मूल प्रक्रिया अपने समापन के लिए इंतजार कर रही है), लेकिन ksh93 इसके बजाय (...)
सभी को एक ही प्रक्रिया में, अंदर कोड चलाने पर होगा :
- याद रखें कि यह एक उप-वातावरण में है।
- पर
cd
, पिछले कार्यशील निर्देशिका (आमतौर पर एक फ़ाइल वर्णनकर्ता O_CLOEXEC के साथ खुला पर), OLDPWD का मूल्य, लोक निर्माण विभाग चर और कुछ भी बचाने कि बचाने cd
को संशोधित कर सकते हैं और उसके बाद करनाchdir("/bar")
- उपधारा से लौटने पर, वर्तमान कार्यशील निर्देशिका (
fchdir()
उस पर सहेजे गए fd के साथ) को पुनर्स्थापित किया जाता है , और सब कुछ जो उपधारा संशोधित हो सकता है।
ऐसे संदर्भ हैं जहां एक बच्चे की प्रक्रिया से बचा नहीं जा सकता है। ksh93 में कांटा नहीं है:
var=$(subshell)
(subshell)
लेकिन में करता है
{ subshell; } &
{ subshell; } | other command
यही है, ऐसे मामले जहां चीजों को अलग-अलग प्रक्रियाओं में चलाना होता है ताकि वे समवर्ती रूप से चल सकें।
ksh93 अनुकूलन उससे आगे जाते हैं। उदाहरण के लिए, जबकि में
var=$(pwd)
अधिकांश गोले एक प्रक्रिया को कांटा करते हैं, बच्चे pwd
को अपने डंडे के साथ कमांड को एक पाइप पर पुनर्निर्देशित किया जाता है, pwd
उस पाइप के लिए वर्तमान कार्यशील निर्देशिका लिखें, और मूल प्रक्रिया पाइप के दूसरे छोर पर परिणाम को पढ़ती है, ksh93
सभी को वर्चुअलाइज करती है और न ही कांटा की आवश्यकता है और न ही पाइप की। कांटा और पाइप का उपयोग केवल गैर-अंतर्निहित कमांड के लिए किया जाएगा।
ध्यान दें कि ऐसे अन्य संदर्भ हैं जो शंख को खोलते हैं, जिसके लिए एक बच्चे की प्रक्रिया को कांटा जाता है। उदाहरण के लिए, एक कमांड को चलाने के लिए एक अलग निष्पादन योग्य में संग्रहीत किया जाता है (और यह एक ही शेल दुभाषिया के लिए एक स्क्रिप्ट नहीं है), एक शेल को उस कमांड को चलाने के लिए एक प्रक्रिया को छोड़ना होगा क्योंकि इसमें अन्यथा नहीं होगा उस आदेश के बाद अधिक कमांड चलाने में सक्षम।
में:
/bin/echo "$((n += 1))"
यह एक उपधारा नहीं है, वर्तमान शेल निष्पादन वातावरण में कमांड का मूल्यांकन किया जाएगा, वर्तमान शेल निष्पादन पर्यावरण के n
चर को बढ़ाया जाएगा, लेकिन शेल उस तर्क /bin/echo
के विस्तार के साथ उस आदेश को निष्पादित करने के लिए एक बच्चे की प्रक्रिया को कांटा देगा। $((n += 1))
।
कई गोले एक अनुकूलन को लागू करते हैं कि वे उस बाहरी आदेश को चलाने के लिए एक बच्चे की प्रक्रिया को कांटा नहीं करते हैं यदि यह एक स्क्रिप्ट या एक उपधारा की अंतिम कमान है (उन उपधाराओं के लिए जिन्हें बाल प्रक्रियाओं के रूप में लागू किया जाता है)। ( bash
हालाँकि यह केवल तभी होता है यदि वह कमांड सबस्क्रिप्शन का एकमात्र कमांड है)।
इसका मतलब यह है कि, उन गोले के साथ, यदि उप-क्रम में अंतिम कमांड एक बाहरी कमांड है, तो उप-समूह अतिरिक्त प्रक्रिया का कारण नहीं बनता है। यदि आप तुलना करते हैं:
a=1; /bin/echo "$a"; a=2; /bin/echo "$a"
साथ में
a=1; /bin/echo "$a"; (a=2; /bin/echo "$a")
एक ही संख्या में प्रक्रियाएं बनाई जाएंगी, केवल दूसरे मामले में, दूसरा कांटा पहले किया जाता है ताकि a=2
उप-परिवेश में चलाया जाए ।