बाद के लिए बाहर निकलें कोड सहेजें


15

इसलिए मेरे पास कुछ परीक्षण चलाने के लिए थोड़ी स्क्रिप्ट है।

javac *.java && java -ea Test
rm -f *.class

अब इसके साथ समस्या यह है कि जब मैं स्क्रिप्ट चलाऊंगा ./test, तो यह एक सफलता निकास कोड लौटा देगा भले ही परीक्षण विफल हो जाता है क्योंकि rm -f *.classसफल होता है।

एक ही तरीका है कि मैं इसे पाने के बारे में सोच सकता हूं जो मैं चाहता हूं वह मुझे बदसूरत लगता है:

javac *.java && java -ea Test
test_exit_code=$?
rm -f *.class
if [ "$test_exit_code" != 0 ] ; then false; fi

लेकिन यह कुछ सामान्य समस्या की तरह लगता है - एक कार्य करना, सफाई करना, फिर मूल कार्य के निकास कोड को वापस करना।

ऐसा करने का सबसे मुहावरेदार तरीका क्या है (सामान्य तौर पर बैश या सिर्फ गोले में)?

जवाबों:


5

आप लपेट कर सकते हैं exitऔर rmसाथ एक एकल सरल-आदेश में आदेश evalकी तरह:

java ... && java ...
eval "rm -f *.class; exit $?"

इस तरह से $?मूल्य जब पारित किया exitजाता है जो कुछ भी होता है उसे तुरंत evalरन से पहले सौंपा जाता है ।


evalहमेशा एक प्रशंसक पसंदीदा है।
15

23

मैं साथ जाऊँगा:

javac *.java && java -ea Test
test_exit_code=$?
rm -f *.class
exit "$test_exit_code"

exitउपलब्ध होने पर क्यों कूदते हैं ?


आप एक का उपयोग कर सकते हैं trap:

trap 'last_error_code=$?' ERR

उदाहरण के लिए:

$ trap 'last_error_code=$?' ERR
$ false
$ echo $?
1
$ echo $last_error_code $?
1 0

आह मैं मानता हूं कि यह मेरे मूल से बेहतर है। लेकिन यह अभी भी असंतोषजनक लगता है कि मुझे एक्ज़िट कोड को एक चर में स्पष्ट रूप से संग्रहीत करना है। क्या एक्ज़िट कोड को 'पुश' करने और बाद में इसे फिर से 'पॉप' करने का कोई तरीका नहीं है?
math4tots

@ math4tots अद्यतन का प्रयास करें।
मुरु

तो आपके अपडेट के साथ मुझे last_error_code को शून्य में इनिशियलाइज़ करना होगा और फिर अंत में लौटना होगा, इसलिए यदि कोई कमांड किसी एरर को फेंके तो मेरे पास नॉन-जीरो एग्जिट कोड होगा? यह एक अच्छी चाल है, लेकिन मेरी दो लाइन हैक स्क्रिप्ट के लिए, मुझे लगता है कि मुझे @mikeserv का जवाब पसंद है।
math4tots

@ math4tots आप हमेशा कर सकते हैं exit ${last_error_code:=0}
मुरु

@avip के लिए जो भी हो? यह पहले से ही एकल उद्धरणों में है, इसलिए चर का मूल्यांकन केवल तब किया जाता है जब जाल कहा जाता है।
मुरु

9

जहाँ तक मुझे पता है कि निकटतम चीज़ बैश को try...finallyएक अधिक सी-लाइक प्रोग्रामिंग लैंग्वेज से ब्लॉक किया गया है (जो कि शायद आप चाहें तो उपलब्ध हो) यह trapकंस्ट्रक्शन है, जो इस तरह से काम करता है:

trap "rm -f *.class" EXIT
javac *.java && java -ea Test

आपकी स्क्रिप्ट से बाहर निकलने पर यह "rm -f * .class" निष्पादित करेगा। यदि आपके पास करने के लिए कुछ अधिक जटिल है, तो आप इसे एक समारोह में रख सकते हैं:

cleanup() {
    ...
}
trap cleanup EXIT
javac *.java && java -ea Test

यदि आप इतने इच्छुक हैं, तो आप इसे एक सामान्य सामान्य मुहावरे में बदल सकते हैं try...catch...finallyजो सी में ब्लॉक की तरह काम करता है। कुछ इस तरह से:

(
  trap "catch_block; exit" ERR
  trap finally_block EXIT
  # contents of try goes here
)

ध्यान दें कि कोष्ठक एक उपधारा का परिसीमन करता है; इस निर्माण के साथ, केवल उप-प्रकार बाहर निकलता है यदि कोई कमांड विफल हो जाती है, संपूर्ण स्क्रिप्ट नहीं। याद रखें कि उप-भाग कुछ कम्प्यूटेशनल रूप से महंगे हैं, इसलिए उनमें से बहुत सारे (सैकड़ों) का उपयोग न करें। अपनी स्क्रिप्ट के आधार पर आप शेल फ़ंक्शन के साथ और अधिक कुशलता से एक ही प्रभाव प्राप्त करने में सक्षम हो सकते हैं trap ... RETURN, लेकिन इसकी जांच करना आपके ऊपर है।

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