अगर एक कमांड सफल हुआ तो कैसे जांचें?


234

क्या यह जांचने का कोई तरीका है कि क्या कमांड निष्पादित करने में कोई त्रुटि है?

उदाहरण :

test1=`sed -i "/:@/c connection.url=jdbc:oracle:thin:@$ip:1521:$dataBase" $search`
valid $test1

function valid () {
  if $test -eq 1; then
    echo "OK"
    else echo "ERROR" 
  fi
}

मैंने पहले से ही ऐसा करने की कोशिश की, लेकिन ऐसा लगता है कि यह काम नहीं कर रहा है। मैं नहीं करता कि कैसे करते हैं।


9
बैकटिक्स `फू` पर $ (फू) को प्राथमिकता दें , क्योंकि आप इसे घोंसला बना सकते हैं, और एपोस्ट्रोफ से अलग करना आसान है।
उपयोगकर्ता अज्ञात

1
BTW, validआपको कॉल करने से पहले एक फ़ंक्शन ( ) को परिभाषित करने की आवश्यकता है।
वंदारेरी

जवाबों:


344

वापसी मूल्य में संग्रहीत किया जाता है $?। 0 सफलता इंगित करता है, अन्य त्रुटि इंगित करता है।

some_command
if [ $? -eq 0 ]; then
    echo OK
else
    echo FAIL
fi

किसी भी अन्य पाठ मूल्य की तरह, आप इसे भविष्य की तुलना के लिए एक चर में संग्रहीत कर सकते हैं:

some_command
retval=$?
do_something $retval
if [ $retval -ne 0 ]; then
    echo "Return code was not zero but $retval"
fi

संभावित तुलना ऑपरेटरों के लिए, देखें man test


यह अच्छा है ... मैं उत्पादन त्रुटि पकड़ कर सकते हैं ?? !! , क्योंकि इस मामले में मेरे पास 2 त्रुटि है: कमांड त्रुटि "पाठ" पूर्व, फ़ाइल नहीं मिली और मेरी त्रुटि "पाठ" जो इस मामले में है उदाहरण के लिए विफल
moata_u

@moata_u: आप मेरे उत्तर में दिखाए गए मान के अनुसार चर में संग्रह कर सकते हैं।
लेकेनस्टाइन

@moata_u: आपको एक ;से पहले डालने की आवश्यकता है elseऔर fi: `अगर ...; फिर ...; अन्य ...; फाई
लेकेन्स्टाइन


1
@ बलौर्न [ $? ](या समतुल्य test $?) , $?किसी संख्या (0, 1, आदि) का मूल्यांकन करने के लिए काम नहीं करता है जो शून्य नहीं है। इसके लिए डॉक्सtest देखें : "यदि परीक्षा छोड़ दी जाती है, तो 'परीक्षण' गलत हो जाता है। यदि परीक्षा एकल तर्क है, तो 'परीक्षण' गलत है, यदि तर्क शून्य है और अन्यथा सत्य है।"
लीकेनस्टाइन

87

यदि आपको केवल यह जानने की आवश्यकता है कि क्या कमांड सफल या विफल हुआ है, तो परीक्षण को परेशान न करें $?, बस सीधे कमांड का परीक्षण करें। उदाहरण के लिए:

if some_command; then
    printf 'some_command succeeded\n'
else
    printf 'some_command failed\n'
fi

और आउटपुट को एक चर में नियत करने से रिटर्न वैल्यू में बदलाव नहीं होता है (ठीक है, जब तक कि यह अलग तरह से व्यवहार नहीं करता है जब stdout कोर्स का टर्मिनल नहीं है)।

if output=$(some_command); then
    printf 'some_command succeded, the output was «%s»\n' "$output"
fi

http://mywiki.wooledge.org/BashGuide/TestsAndConditionalsif अधिक विस्तार से बताते हैं ।


क्या होगा अगर आप ब्रांचिंग के अलावा कुछ करना चाहते हैं जैसे कि बूलियन को स्टोर करना चाहे वो असफल हो या नहीं। तब आपका आउटपुट वैरिएबल ऐसा नहीं करता है, लेकिन $?करता है, तो आप यह कहने में गलत हैं कि कमांड का सीधे परीक्षण करना कड़ाई से बेहतर है।
टिमोथी स्वान

एक चर करने के लिए उत्पादन नियत वापसी मान बदल सकता है जब एक का उपयोग करता localआदेश, यानी local foo=$(false); echo $?;पैदा करता है 0उत्पादन पर। लेकिन localकेवल बैश कार्यों के अंदर ही प्रासंगिक है।
क्रेन

26
command && echo OK || echo Failed

यदि commandस्क्रीन पर त्रुटि वापस आती है, तो इसे कैसे छिपाएं?
सिगुर

यदि commandआप stderr के लिए त्रुटियाँ लिखते हैं, तो आप फ़ॉर्म का उपयोग कर सकते हैं command 2> /dev/null && echo OK || echo Failed2> /dev/nullरीडायरेक्ट करने के लिए उत्पादन stderr /dev/null। हालांकि, कुछ उपयोगिताएँ स्टडआउट (भले ही यह बुरा अभ्यास हो) में त्रुटियां लिखेंगे। इस मामले में आप पुनर्निर्देशन से 2 को छोड़ सकते हैं, लेकिन आप कमांड से किसी भी आउटपुट को खो देंगे। सफलता की जाँच करने का यह तरीका सरल त्रिगुट तर्क के लिए अच्छा है, लेकिन अधिक जटिल व्यवहार के लिए यह $?कमांड की सफलता के लिए सबसे अच्छा है , या if@ जिरह के उत्तर में उल्लिखित ब्लॉक विधि का उपयोग करें ।
सबसे बड़ा

17

$? पिछली कमांड की निकास स्थिति होनी चाहिए, जो बिना किसी त्रुटि के शून्य होनी चाहिए।

तो, कुछ इस तरह;

cd /nonexistant
if [ $? -ne 0 ]
then
    echo failed
else
    echo success!
fi

अधिकांश मामलों के लिए, श्रृंखला आदेशों के लिए && निर्माण का उपयोग करना आसान है जिन्हें एक दूसरे पर निर्भर होने की आवश्यकता होती है। इसलिए सफलता की गूंज नहींcd /nonexistant && echo success! होगी क्योंकि कमांड & से पहले टूट जाती है। इस का मूलाधार है ||, जहाँ प्रतिध्वनि विफल होगी क्योंकि cd विफल (यह उपयोगी हो जाता है यदि आप कुछ का उपयोग करते हैं जैसे कि बाहर निकलें। यदि स्क्रिप्ट पिछली कमांड विफल हो गई तो समाप्त हो जाएगी।)cd /nonexistant || echo fail


यह अच्छा है ... मैं उत्पादन त्रुटि पकड़ कर सकते हैं ?? !! , क्योंकि इस मामले में मैं 2 त्रुटि है: कमांड त्रुटि "पाठ" पूर्व, फ़ाइल नहीं मिली और मेरी त्रुटि "पाठ" जो इस मामले में है उदाहरण के लिए विफल
moata_u


5
command && echo $? || echo $?

तुम्हारा मतलब है command; echo $??
जेवियर बूज़ी

नहीं, मेरी लाइन सही है, यह सफलता या असफलता की परवाह किए बिना संख्या के रूप में वास्तविक परिणाम कोड देता है।
न्यूट्रोब नोव

1
ठीक है, कृपया मुझे इन के अंतरों की व्याख्या करें: true && echo $? || echo $?/ true; echo $?और false && echo $? || echo $?/ false; echo $?- आप पाएंगे, वे ठीक यही काम करते हैं: डी
जेवियर बुज़ी

हां, वही परिणाम लेकिन शर्त के बिना। मूल प्रश्न पूछा गया था कि "यह कैसे जांचें कि क्या कोई कमांड सफल हुआ?", यह पिछले उत्तरों पर आधारित था। मुझे लगता है कि एक बेहतर उदाहरण होगा:command && echo "success: $?" || echo "fail: $?"
modrobert

5

यह ध्यान दिया जाना चाहिए कि / if...then...fiऔर प्रकार के दृष्टिकोण से बाहर निकलने की स्थिति से संबंधित सौदे हम कमांड द्वारा परीक्षण करना चाहते हैं (सफलता पर 0); हालाँकि, कुछ कमांड नॉन-जीरो एग्जिट स्टेटस नहीं लौटाते हैं यदि कमांड विफल हो जाता है या इनपुट से निपट नहीं सकता है। इसका मतलब यह है कि सामान्य और / दृष्टिकोण उन विशेष कमांड के लिए काम नहीं करेंगे।&&||if&&||

उदाहरण के लिए, लिनक्स GNU पर fileअभी भी 0 के साथ बाहर निकलता है अगर इसे तर्क के रूप में एक गैर-मौजूदा फ़ाइल प्राप्त हुई और findनिर्दिष्ट फ़ाइल उपयोगकर्ता का पता नहीं लगा सका।

$ find . -name "not_existing_file"                                          
$ echo $?
0
$ file ./not_existing_file                                                  
./not_existing_file: cannot open `./not_existing_file' (No such file or directory)
$ echo $?
0

ऐसे मामलों में, एक संभावित तरीका जिसे हम स्थिति को संभाल सकते हैं stderr/ पढ़ सकते हैं stdinसंदेश, जैसे कि fileकमांड द्वारा लौटाए गए , या कमांड के पार्स आउटपुट जैसे find। उस उद्देश्य के लिए, caseकथन का उपयोग किया जा सकता है।

$ file ./doesntexist  | while IFS= read -r output; do                                                                                                                  
> case "$output" in 
> *"No such file or directory"*) printf "%s\n" "This will show up if failed";;
> *) printf "%s\n" "This will show up if succeeded" ;;
> esac
> done
This will show up if failed

$ find . -name "doesn'texist" | if ! read IFS= out; then echo "File not found"; fi                                                                                     
File not found

(यह unix.stackexchange.com पर संबंधित प्रश्न पर मेरे स्वयं के उत्तर का एक भंडार है )


1

जैसा कि कई अन्य उत्तरों में बताया गया $?है, इस तरह की एक सरल परीक्षा होगी

if [ $? -eq 0 ]; then something; fi

यदि आप परीक्षण करना चाहते हैं यदि कमांड विफल हो गया है , तो आप bashनिम्न रूप में (लेकिन शायद ओवरकिल) एक छोटे संस्करण का उपयोग कर सकते हैं :

if (($?)); then something; fi

यह (( ))अंकगणित मोड का उपयोग करके काम करता है , इसलिए यदि कमांड वापस आ गया है success, $? = 0तो यह परीक्षण मूल्यांकन करता है कि ((0))कौन सा परीक्षण करना है false, अन्यथा यह वापस आ जाएगा true

सफलता के लिए परीक्षण करने के लिए , आप उपयोग कर सकते हैं:

if ! (($?)); then something; fi

लेकिन यह पहले से ही पहले उदाहरण की तुलना में बहुत कम नहीं है।


1
रचनात्मक आलोचना?
afun

0

अपने आदेशों को प्रमाणित करने में त्रुटि के लिए :

execute [INVOKING-FUNCTION] [COMMAND]

execute () {
    error=$($2 2>&1 >/dev/null)

    if [ $? -ne 0 ]; then
        echo "$1: $error"
        exit 1
    fi
}

झुक विनिर्माण में प्रेरित :


-2

अगर [$ (कमांड)]; तब गूंज "सफल"; फाई


3
trueसफल होता है, if [ $(true) ]; then echo "succeed"; fiलेकिन succeedमुद्रित नहीं होता है । वास्तव में यह कभी commandसफल नहीं होता है। इसे जिरह की मुद्राif command में उपयोग करना चाहिए । है आदेश प्रतिस्थापन । एक सशर्त अभिव्यक्ति है । अनुपस्थित शब्द विभाजन और फ़ाइल नाम का विस्तार , यह मूल रूप से परीक्षण करता है यदि आउटपुट था। $( )[ ]command
एलिया कगन
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.