एक्जिट कमांड के एक्जिट कोड को कैप्चर करें


10

मेरे पास एक बैश स्क्रिप्ट में यह है:

exit 3;

exit_code="$?"

if [[ "$exit_code" != "0" ]]; then
    echo -e "${r2g_magenta}Your r2g process is exiting with code $exit_code.${r2g_no_color}";
    exit "$exit_code";
fi

ऐसा लगता है कि यह निकास कमान के ठीक बाद बाहर निकल जाएगा, जो समझ में आता है। मैं सोच रहा था कि क्या कोई सरल कमांड है जो तुरंत बाहर निकलने के बिना एक निकास कोड प्रदान कर सकता है?

मैं अनुमान लगाने वाला था:

exec exit 3

लेकिन यह एक त्रुटि संदेश देता है exec: exit: not found:। मैं क्या कर सकता हूँ? :)


1
हाँ exec exit 3, कोई "exec: exit: not found"

7
मुझे सवाल समझ नहीं आ रहा है। क्यों नहीं सेट exit_code=3और exit 3पूरी तरह से खत्म लाइन?
wjandrea

@wandrea व्यावहारिक से अधिक एक वैचारिक प्रश्न है

2
यह अभी भी मुझे कोई मतलब नहीं है। यदि आप वास्तव में बाहर नहीं निकलते हैं तो एक निकास कोड क्यों होगा?
बरमार

1
@ बरमार हर प्रक्रिया का एक एक्जिट कोड होता है। सवाल का जवाब देने की कोशिश करने वाले अधिकांश लोग इस सवाल का अर्थ पूछ रहे हैं कि "मैं 'एग्जिट 3' को स्क्रिप्ट में बदल सकता हूं, इसलिए यह $?वेरिएबल सेट करता है, लेकिन इस स्क्रिप्ट से बाहर नहीं निकलता "?
इकारस

जवाबों:


32

यदि आपके पास एक स्क्रिप्ट है जो कुछ प्रोग्राम चलाती है और प्रोग्राम के एग्जिट स्टेटस (साथ $?) को देखती है  , और आप उस स्क्रिप्ट को कुछ ऐसा करके टेस्ट करना चाहते हैं जो $?कुछ ज्ञात मूल्य (जैसे 3) पर सेट होने का कारण बनता है  , तो बस करें

(exit 3)

कोष्ठक एक उप-शेल बनाते हैं। तब exitकमांड उस उप-शेल को निर्दिष्ट निकास स्थिति के साथ बाहर निकलने का कारण बनता है।


डिबगिंग के प्रयोजनों के लिए, यह exit_code="3"परीक्षण के लिए सेट करने के लिए बस उतना ही सरल होगा
सेंटिमेन


12

exitएक बैश बिल्ट-इन है, इसलिए आप इसे नहीं कर सकते exec। प्रति बैश मैनुअल :

बैश की निकास स्थिति स्क्रिप्ट में निष्पादित अंतिम कमांड की निकास स्थिति है। यदि कोई कमांड निष्पादित नहीं होती है, तो निकास स्थिति 0 है।

यह सब एक साथ रखते हुए, मैं कहूंगा कि आपका एकमात्र विकल्प आपकी इच्छित निकास स्थिति को एक चर में संग्रहीत करना है और फिर exit $MY_EXIT_STATUSजब उचित हो।


@ हम-जी के विचार के बारे में आप क्या सोचते हैं?

2
शायद मैं गलत समझ रहा हूं कि आप क्या हासिल करने की कोशिश कर रहे हैं। यदि आप बस सेट करने की कोशिश कर रहे हैं $?(हालांकि मैं वास्तव में आपको क्यों पता नहीं है), तो यह एक ठोस जवाब की तरह लगता है। यदि आप इसे कुछ असफल मान पर सेट करना चाहते हैं, falseतो एक और विकल्प है।
सोलारसादो

10

आप एक फ़ंक्शन लिख सकते हैं जो दिए गए स्थिति को तर्क के रूप में लौटाता है, या 255यदि कोई नहीं दिया गया है। (मैं retइसे "रिटर्न" मान के रूप में कहता हूं ।)

ret() { return "${1:-255}"; }

और retअपने कॉल के स्थान पर उपयोग करें exit। यह वर्तमान में स्वीकृत उत्तर में उप-शेल बनाने की अक्षमता से बचा जाता है।

कुछ माप।

time bash -c 'for i in {1..10000} ; do (exit 3) ; done ; echo $?'

मेरी मशीन में लगभग 3.5 सेकंड लगते हैं।

 time bash -c 'ret(){ return $1 ; } ; for i in {1..10000} ; do ret 3 ; done ; echo $?'

मेरी मशीन में 70 गुना तेजी से 0.051 सेकंड लगते हैं। डिफ़ॉल्ट हैंडलिंग में अभी भी इसे 60 गुना तेजी से छोड़ रहा है। जाहिर है कि लूप में कुछ ओवरहेड है। यदि मैं लूप के शरीर को सिर्फ :या trueतो बदल देता हूं या फिर समय 0.025 तक आधा हो जाता है, तो एक पूरी तरह से खाली लूप अमान्य वाक्यविन्यास है। ;:लूप में जोड़ने से पता चलता है कि यह न्यूनतम कमांड 0.007 सेकंड लेता है, इसलिए लूप ओवरहेड 0.018 के बारे में है। दो परीक्षणों से इस ओवरहेड को घटाना यह दर्शाता है कि retसमाधान 100 गुना अधिक तेजी से है।

जाहिर है कि यह एक सिंथेटिक माप है, लेकिन चीजें बढ़ जाती हैं। यदि आप सबकुछ 100 गुना धीमा कर देते हैं, तो आपको धीमे सिस्टम के साथ समाप्त होने की आवश्यकता है। 0.0


2
@iBug अतिरिक्त स्थान की आवश्यकता नहीं है।
इकारस

उप-शेल बनाने की अक्षमता के बारे में अच्छी बात। मैंने पढ़ा है कि इस तरह के मामलों में कांटा बाहर निकालने के लिए कुछ गोले काफी स्मार्ट हो सकते हैं, लेकिन यह बैश उनमें से एक नहीं है।
जी-मैन का कहना है कि 'मोनिका

3

के बारे में exec exit 3... यह नामक एक बाहरी कमांड को चलाने की कोशिश करेगा exit, लेकिन एक नहीं है, इसलिए आपको त्रुटि मिलती है। शेल में निर्मित एक के बजाय एक बाहरी कमांड होना चाहिए, क्योंकि शेल पूरी तरह से exec बदल जाता है। भी जिसका अर्थ है कि भले ही आप बुलाया एक बाहरी आदेश था exit, exec exit 3अपने खोल स्क्रिप्ट जारी रखने के लिए वापस नहीं होगा, के बाद से खोल वहाँ किसी भी अधिक नहीं होगा


1
मुझे लगता है कि आप कर सकते हैं exec bash -c "exit 3", लेकिन फिलहाल मैं ऐसा करने के लिए किसी भी कारण के बारे में सोच भी नहीं सकता exit 3
डेविड जेड

1
@ डेविड, किसी भी मामले में, exec'आईएनजी या सिर्फ exit' आईएनजी स्क्रिप्ट को रोक देगा, जो ऐसा नहीं लगता था कि प्रश्न क्या चाहता था।
ilkachachu

3

आप इसे अवाक से कर सकते हैं:

awk 'BEGIN{exit 9}'

या पाल:

sed Q9 /proc/stat

... या एक खोल के साथ:sh -c 'exit 9'
ilkkachu

1
@ तिलकचू यदि आप ऐसा करने जा रहे हैं तो आप (exit 9)स्वीकृत उत्तर में भी कर सकते हैं
स्टीवन पेनी
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.