बश में कब () बनाम {} का उपयोग करें?


74

मैं बैश के साथ शेल स्क्रिप्टिंग का अध्ययन कर रहा हूं और मुझे (...)और के बीच का अंतर जानने की जरूरत है {...}। स्क्रिप्ट लिखते समय दोनों के बीच चयन कैसे होता है?



3
आप केवल कमांड ग्रुपिंग के संदर्भ में थे?
हेमेयेल

जवाबों:


87

यदि आप अपने वर्तमान शेल को प्रभावित करने के लिए कमांड सूची के साइड-इफेक्ट्स चाहते हैं , तो उपयोग करें {...}
यदि आप कोई साइड-इफेक्ट्स को छोड़ना चाहते हैं, तो उपयोग करें(...)

उदाहरण के लिए, अगर मैं:

  • $IFSकुछ आदेशों के लिए परिवर्तन करना चाहते हैं , लेकिन मैं $IFSवर्तमान शेल के लिए विश्व स्तर पर परिवर्तन नहीं करना चाहता
  • cdकहीं, लेकिन मैं $PWDवर्तमान शेल के लिए बदलना नहीं चाहता

यह ध्यान देने योग्य है कि कोष्ठक का उपयोग फ़ंक्शन परिभाषा में किया जा सकता है:

  • सामान्य उपयोग: ब्रेसिज़: फ़ंक्शन बॉडी वर्तमान शेल में निष्पादित होती है; फंक्शन पूरा होने के बाद साइड-इफेक्ट्स रहते हैं

    $ count_tmp() { cd /tmp; files=(*); echo "${#files[@]}"; }
    $ pwd; count_tmp; pwd
    /home/jackman
    11
    /tmp
    $ echo "${#files[@]}"
    11    
    
  • असामान्य उपयोग: कोष्ठक: एक उपधारा में फ़ंक्शन बॉडी निष्पादित होती है; साइड-इफ़ेक्ट तब गायब हो जाते हैं जब सबस्क्रिप्शन बाहर निकल जाता है

    $ cd ; unset files
    $ count_tmp() (cd /tmp; files=(*); echo "${#files[@]}")
    $ pwd; count_tmp; pwd
    /home/jackman
    11
    /home/jackman
    $ echo "${#files[@]}"
    0
    

प्रलेखन


11
शेल विकास के कई वर्षों के बाद, मुझे नहीं पता था कि आप उपधारा में फ़ंक्शन चलाने के लिए कोष्ठक का उपयोग कर सकते हैं। वैश्विक नाम स्थान को प्रदूषित करने से बचने के लिए क्या शानदार विचार है!
l0b0

7
localकीवर्ड का उपयोग करने से उस प्रदूषण को साफ करने में काफी मदद मिलती है।
ग्लेन जैकमैन

2
हाँ, लेकिन आपको प्रत्येक चर को स्थानीय घोषित करना याद रखना होगा, और यह कोड को बंद कर देगा।
l0b0

4
संकेत: यदि आप साइड-इफ़ेक्ट-फ़्री फ़ंक्शंस चाहते हैं, लेकिन असामान्य फ़ंक्शन डिक्लेरेशन सिंटैक्स से बचें (जो कोड एडिटर्स को पता नहीं हो सकता है) तो बस डिक्लेरेशन के बजाय फंक्शन कॉल पर कोष्ठक का उपयोग करें:pwd; (count_tmp); pwd;
Juve

2
खोल के लिए ... फू () (:;) फू के बराबर है () {(;); } अगर आप पूछें कि यह कैसे रिपोर्ट करता है!
एंथनी

23

आधिकारिक बैश प्रलेखन से :

()

( list )

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

{}

{ list; }

घुंघराले ब्रेसिज़ के बीच आदेशों की एक सूची रखने से सूची को वर्तमान शेल संदर्भ में निष्पादित किया जा सकता है। कोई सबस्क्रिप्शन नहीं बनाया जाता है। सूची के बाद अर्धविराम (या नई पंक्ति) की आवश्यकता है।


9

Thread {} ’में कोड को वर्तमान थ्रेड / प्रक्रिया / वातावरण में निष्पादित किया जाता है और परिवर्तनों को संरक्षित किया जाता है, इसे अधिक संक्षिप्त रूप से डालने के लिए, कोड को वर्तमान दायरे में चलाया जाता है।
कोड इन '()' को अलग-अलग बैश की बाल प्रक्रिया के अंदर चलाया जाता है, जिसे निष्पादन के बाद छोड़ दिया जाता है। इस बच्चे की प्रक्रिया को अक्सर उप-शेल के रूप में संदर्भित किया जाता है और इसे एक नए, बच्चे जैसी गुंजाइश के रूप में सोचा जा सकता है।

एक उदाहरण के रूप में निम्नलिखित पर विचार करें ...

 ~ # { test_var=test }
 ~ # echo $test_var
 test
 ~ # ( test_var2=test2 )
 ~ # echo $test_var2

 ~ # 

'{}' के साथ पहले उदाहरण में सूचना '' '' को बंद करने के बाद भी परिवर्तनशील है, जबकि '()' के उदाहरण में चर '()' के दायरे से बाहर सेट नहीं है।


4

(...)उप-शेल में कोड चलाने के लिए उपयोग किया जाता है। उपयोग किए जाने वाले कोड को {...}उप-शेल में उपयोग नहीं किया जाएगा।

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