त्रुटि पर एक स्क्रिप्ट से बाहर निकलें


141

मैं एक शेल स्क्रिप्ट का निर्माण कर रहा हूं जिसमें ifइस तरह का एक फ़ंक्शन है:

if jarsigner -verbose -keystore $keyst -keystore $pass $jar_file $kalias
then
    echo $jar_file signed sucessfully
else
    echo ERROR: Failed to sign $jar_file. Please recheck the variables
fi

...

मैं त्रुटि संदेश प्रदर्शित करने के बाद स्क्रिप्ट का निष्पादन समाप्त करना चाहता हूं। मैं यह कैसे कर सकता हूं?

जवाबों:


137

क्या आप ढूंढ रहे हैं exit?

यह सबसे अच्छा बैश गाइड है। http://tldp.org/LDP/abs/html/

प्रसंग में:

if jarsigner -verbose -keystore $keyst -keystore $pass $jar_file $kalias
then
    echo $jar_file signed sucessfully
else
    echo ERROR: Failed to sign $jar_file. Please recheck the variables 1>&2
    exit 1 # terminate and indicate error
fi

...

5
यदि आप ABS को पसंद करते हैं, तो आप बैशगाइड , BashFAQ और BashPitfalls पसंद करेंगे
अगली सूचना तक रोक दिया गया।

उन बैश लिंक भयानक हैं! BashFAQ BashRecipes के रूप में बेहतर स्थिति में होगा।
पीट एल्विन

337

यदि आप set -eएक स्क्रिप्ट में डालते हैं , तो स्क्रिप्ट समाप्त हो जाएगी जैसे ही उसके अंदर कोई भी कमांड विफल हो जाती है (जैसे ही कोई कमांड नॉनवेज स्टेटस लौटाता है)। यह आपको अपना संदेश लिखने की अनुमति नहीं देता है, लेकिन अक्सर असफल कमांड के स्वयं के संदेश पर्याप्त होते हैं।

इस दृष्टिकोण का लाभ यह है कि यह स्वचालित है: आप एक त्रुटि मामले से निपटने के लिए भूलने का जोखिम नहीं चलाते हैं।

जिन शर्तों को किसी सशर्त (जैसे if, &&या ||) द्वारा परीक्षण किया जाता है वे स्क्रिप्ट को समाप्त नहीं करते हैं (अन्यथा सशर्त व्यर्थ होगा)। सामयिक आदेश के लिए एक मुहावरा जिसकी विफलता कोई मायने नहीं रखती है command-that-may-fail || true। आप set -eस्क्रिप्ट के एक भाग के लिए भी बंद कर सकते हैं set +e


3
Mywiki.wooledge.org/BashFAQ/105 के अनुसार - इस सुविधा का इतिहास अस्पष्ट है और इसके दृढ़ संकल्प में निहित है , जिसमें आदेशों के त्रुटि कोड एक स्वचालित निकास का कारण बनते हैं। इसके अलावा, "नियम एक बैश संस्करण से दूसरे में बदलते हैं, क्योंकि बैश इस 'फीचर' की बेहद फिसलन वाली पॉसिक्स परिभाषा को ट्रैक करने का प्रयास करता है"। मैं @Dennis विलियमसन और के स्वीकार किए जाते हैं जवाब से सहमत stackoverflow.com/questions/19622198/... उपयोग जाल 'error_handler' ERR -। भले ही यह एक जाल है!
बॉन्डोलिन 14

3
अक्सर -xध्वज के साथ ध्वज का उपयोग करना -eट्रेस के लिए पर्याप्त है जहां आपका प्रोग्राम बाहर निकलने पर है। इसका मतलब है कि स्क्रिप्ट का उपयोगकर्ता भी डेवलपर है।
एलेक्स

अच्छा है, लेकिन मुझे लगता है कि ओपी को एक स्व-परिभाषित अपवाद से स्क्रिप्ट से बाहर निकलने की आवश्यकता थी।
vdegenne

42

यदि आप नेत्रहीन बाहर निकलने के बजाय एक त्रुटि को संभालने में सक्षम होना चाहते हैं set -e, तो उपयोग करने के बजाय , छद्म संकेत trapपर उपयोग करें ERR

#!/bin/bash
f () {
    errorCode=$? # save the exit code as the first thing done in the trap function
    echo "error $errorCode"
    echo "the command executing at the time of the error was"
    echo "$BASH_COMMAND"
    echo "on line ${BASH_LINENO[0]}"
    # do some error handling, cleanup, logging, notification
    # $BASH_COMMAND contains the command that was being executed at the time of the trap
    # ${BASH_LINENO[0]} contains the line number in the script of that command
    # exit the script or return to try again, etc.
    exit $errorCode  # or use some other value or do return instead
}
trap f ERR
# do some stuff
false # returns 1 so it triggers the trap
# maybe do some other stuff

अन्य जालों को अन्य संकेतों को संभालने के लिए सेट किया जा सकता है, जिनमें सामान्य यूनिक्स सिग्नल और अन्य बैश छद्म सिग्नल शामिल हैं RETURNऔर DEBUG


8

यहाँ यह करने का तरीका है:

#!/bin/sh

abort()
{
    echo >&2 '
***************
*** ABORTED ***
***************
'
    echo "An error occurred. Exiting..." >&2
    exit 1
}

trap 'abort' 0

set -e

# Add your script below....
# If an error occurs, the abort() function will be called.
#----------------------------------------------------------
# ===> Your script goes here
# Done!
trap : 0

echo >&2 '
************
*** DONE *** 
************
'

क्यों Stderr के लिए किया गया संदेश?
मैटबियनको

1
यह एक सामान्य अभ्यास है इसलिए आप अपने स्क्रिप्ट आउटपुट को स्टडआउट करने के लिए पाइप कर सकते हैं ताकि कोई अन्य प्रक्रिया बीच में जानकारी संदेशों के बिना प्राप्त कर सके।
सुपरकोबरा

2
समस्याओं के एक संकेत के रूप में स्टडर पर कुछ भी व्यवहार करना संभवतः समान रूप से सामान्य अभ्यास है।
मैटबिएनको

1
अतीत में 'सेट-ई' ने हमेशा मेरे लिए काम किया है, लेकिन आज रात मैं एक स्थिति में अल्पाइन लिनक्स डॉकर छवि में चला गया, जहां इसका कोई प्रभाव नहीं पड़ा .. इस समाधान ने मेरे लिए काम किया और मुझे काम पर वापस ले लिया। बहुत सराहना की।
सिंथेसाइजरपटेल

@ सुपरकोबरा सामान्य अभ्यास? कहाँ पे?
थोरबजोरन राव एंडरसन

-8

exit 1आपको जो चाहिए वह यह है। 1ताकि आप इसे अगर आप चाहते हैं कहते हैं बदल सकते हैं,,, एक वापसी कोड है 1एक सफल रन मतलब करने के लिए और -1एक विफलता या ऐसा ही कुछ मतलब है।


13
यूनिक्स में, सफलता हमेशा 0. इस का उपयोग करते समय मदद मिल सकती है testया &&या ||
मौविसील

5
मौविसील की टिप्पणी पर विस्तार करने के लिए: शेल स्क्रिप्ट में, 0 का अर्थ हमेशा सफलता होता है, और 1 से 255 का मतलब विफलता है। -1 सीमा से बाहर है (और अक्सर 255 के समान प्रभाव होगा, इसलिए 1 की तरह विफलता)।
गाइल्स का SO- बुराई पर रोक '

@mouviciel, @Gilles: अतिरिक्त जानकारी के लिए धन्यवाद। मुझे बैश से निपटने में कुछ समय हो गया है।
डीजीएच

यह रिटर्न कोड के उपयोग का एक बुरा उदाहरण है, अन्यथा यह एक महान जवाब होगा।
ब्रैड कोच

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