2013-02-20 19 views
11

मैं थोड़ा उलझन में हूं। मेरा लक्ष्य यहां एक गैर-शून्य निकास कोड के साथ बैश स्क्रिप्ट निकास होना है जब स्क्रिप्ट के भीतर कोई भी आदेश विफल हो जाता है। मैं ध्वज का उपयोग करके, मुझे लगता है कि यह सब कुछ होगा, यहां तक ​​कि subshells का उपयोग करते समय भी।कोई सबहेल विफल होने पर फ्लैग-आउट से बाहर क्यों नहीं निकलता है?

#!/bin/bash -e 

(false) 

echo $? 
echo "Line reached!" 

यहाँ उत्पादन जब भाग गया है::

[$]>Tests/Exec/continuous-integration.sh 
1 
Line reached! 

बैश संस्करण: 3.2.25 CentOS

पर
+0

वहाँ पर कोई मौका है आप अपने बैश संस्करण को अपडेट कर सकते हैं, क्योंकि यह सटीक स्क्रिप्ट 4.1.5 में लक्षित है। शायद यह आपका 'झूठा' संस्करण –

उत्तर

8

ऐसा लगता है कि इस के अपने संस्करण से संबंधित है नीचे एक सरल उदाहरण है bash। जिन मशीनों पर मेरे पास पहुंच है, बैश संस्करण 3.1.17 और 3.2.3 9 इस व्यवहार को प्रदर्शित करते हैं, बैश 4.1.5 नहीं है।

हालांकि थोड़ा बदसूरत, एक समाधान है कि दोनों संस्करणों में काम करता है कुछ इस तरह हो सकता है:

#!/bin/bash -e 

(false) || exit $? 

echo $? 
echo "Line reached!" 

बैश स्रोत बदलाव का जो set -e विकल्प के साथ कीड़े से संबंधित में कुछ नोट कर रहे हैं।

+0

आह है, खुदाई के लिए धन्यवाद, यह था! सुझाए गए उत्तर के लिए धन्यवाद, यह वही है जो मैं करूँगा। –

+1

पता नहीं ओएस ओपी क्या है, लेकिन उदा। माउंटेन शेर अभी भी दुर्भाग्य से बैश 3 के साथ जहाजों। –

0

मैंने एल कैपिटन से पहले एसयूएसई 11.3 और मैक ओएस दोनों पर बैश संस्करण 3.2.51 में यह व्यवहार देखा है। एल कैपिटन पर बैश 3.2.57 में "सही" व्यवहार है, यानी बैश की तरह 4.

हालांकि, उपरोक्त प्रस्तावित कार्यवाही, "बाहर निकलें $?" सबहेल के बंद होने वाले माता-पिता के बाद, झंडे के इरादे को हरा देता है इससे कोई फर्क नहीं पड़ता कि बाश का कौन सा संस्करण है। आदमी पार्टी से:

-e बाहर निकलें तुरंत अगर एक साधारण आदेश (ऊपर देखें शेल व्याकरण) बाहर निकल जाता है एक गैर शून्य की स्थिति के साथ । यदि विफल रहता है तो शेल बाहर नहीं निकलता है कमांड सूची का हिस्सा थोड़ी देर के बाद या कीवर्ड तक, किसी 0 कथन में परीक्षण के भाग , & & या || सूची, ...

"सब से बाहर निकलें"? स्पष्ट रूप से एक कमांड सूची के रूप में गिना जाता है; और bash -e ध्वज सबहेल के अंदर किसी भी कमांड पर लागू नहीं होगा। यह प्रयास करें:,

$ set -e 
$ (echo before the error; false; echo after the error, status $?;) || echo after the subshell, status $? 
before the error 
after the error, status 1 
$ 

क्योंकि subshell || द्वारा पीछा किया जाता है कि, चलाया जाता है यहां तक ​​कि सेट -e के साथ "के बाद त्रुटि गूंज"। इतना ही नहीं, सबहेल 0 से बाहर निकलता है, क्योंकि वह "गूंज" भाग गया। तो "|| बाहर निकलें $?" "बाहर निकलें" भी नहीं चलाएगा। शायद हम नहीं चाहते थे!

जहाँ तक मुझे पता है, निम्न सूत्र बैश संस्करणों के साथ संगत है चाहे वे सबशेल के बाद bash -e का सम्मान करें या नहीं।

तुरंत बैश लिपि में हर subshell के समापन कोष्ठक के बाद निम्न पंक्ति जोड़ें:: -e ध्वज रीसेट किया जा करने के लिए होता है, तो यह भी सही ढंग से कार्य

case $?/$- in (0/*) ;; (*/*e*) exit $? ;; esaC# honor bash -e flag when subshell returns