यदि कोई आदेश सफल या विफल हुआ, तो सशर्त रूप से कुछ कैसे करें


283

मैं इस तरह से कैसे कर सकता हूँ?

if "`command` returns any error";
then
    echo "Returned an error"
else
    echo "Proceed..."
fi

जवाबों:


359

यदि कोई आदेश सफल या विफल हुआ, तो सशर्त रूप से कुछ कैसे करें

ठीक वैसा ही बैश का ifबयान करता है:

if command ; then
    echo "Command succeeded"
else
    echo "Command failed"
fi

टिप्पणियों से जानकारी जोड़ना: आपको इस मामले में ... सिंटैक्स का उपयोग करने की आवश्यकता नहीं है । अपने आप में एक कमांड है, जिसके लगभग बराबर है । यह शायद एक में उपयोग करने के लिए सबसे आम कमांड है , जो इस धारणा को जन्म दे सकता है कि यह शेल के सिंटैक्स का हिस्सा है। लेकिन अगर आप यह परखना चाहते हैं कि कोई कमांड सफल हुआ या नहीं, तो सीधे कमांड का उपयोग करें , जैसा कि ऊपर दिखाया गया है।[][testifif

संपादित करें: स्पष्टता के लिए शीर्ष पर प्रश्न उद्धृत किया गया है (यह उत्तर पृष्ठ के शीर्ष के पास दिखाई नहीं देता है)।


11
ध्यान दें कि अर्धविराम महत्वपूर्ण है।
थोरबजोरन रेव एंडरसन

21
या आप बस thenएक अलग लाइन पर रख सकते हैं ।
l0b0

36
@ जो: मुझे लगता है कि आपका मतलब है if ! command ; then ... ; fi[अपने आप में एक आदेश है, और इस मामले में इसकी आवश्यकता नहीं है।
कीथ थॉम्पसन

20
@ जो: मेरे रास्ते में सही होने का गुण भी है। if [ ! command ]निष्पादित नहीं करता है command; यह commandएक स्ट्रिंग के रूप में व्यवहार करता है और इसे सच मानता है क्योंकि इसकी एक गैर-शून्य लंबाई है। कमांड [का एक पर्याय हैtest
कीथ थॉम्पसन

5
उफ़। तुम सही हो।
जो

133

यदि आप शेल कमांड काम करते हैं, तो छोटी चीजों के लिए, आप &&निर्माण का उपयोग कर सकते हैं :

rm -rf somedir && trace_output "Removed the directory"

इसी तरह छोटी चीजों के लिए जो आप चाहते हैं कि जब शेल कमांड विफल हो जाए, तो आप उपयोग कर सकते हैं ||:

rm -rf somedir || exit_on_error "Failed to remove the directory"

अथवा दोनों

rm -rf somedir && trace_output "Removed the directory" || exit_on_error "Failed to remove the directory"

इन निर्माणों के साथ बहुत कुछ करना शायद नासमझी है, लेकिन वे इस अवसर पर नियंत्रण के प्रवाह को बहुत स्पष्ट कर सकते हैं।


3
वे छोटे और (कम से कम कुछ गोले में) तेज होते हैं। मैं एक राक्षस को याद कर रहा हूँ एक मैट्रिक्स इंस्टॉलेशन स्क्रिप्ट जो इन सशर्त निर्माणों के साथ लिखी गई है जिसे मैंने एक बार समझने की कोशिश की ...
vonbrand

101

मूल्य की जाँच करें $?, जिसमें सबसे हालिया कमांड / फ़ंक्शन निष्पादित करने का परिणाम है:

#!/bin/bash

echo "this will work"
RESULT=$?
if [ $RESULT -eq 0 ]; then
  echo success
else
  echo failed
fi

if [ $RESULT == 0 ]; then
  echo success 2
else
  echo failed 2
fi

11
जबकि तकनीकी रूप से सही है (और इस तरह एक डाउनवोट वारंट नहीं कर रहा है), यह बैश के ifमुहावरे का उपयोग नहीं कर रहा है । मुझे कीथ थॉम्पसन का उत्तर पसंद है।
जम्मोसेन

16
इस मुहावरे के लाभ हैं - यह रिटर्न वैल्यू को संरक्षित करता है। सभी में, मुझे यह अधिक शक्तिशाली लगता है, हालांकि अधिक क्रिया है। इसे पढ़ना भी आसान है।
टैक्सियन

2
"बैश की अगर मुहावरा है" तो क्या होगा?
Nowaker

3
@ नोवेकर तथ्य यह है कि ऐसा करने का एकमात्र उद्देश्य ifहै। बैश में प्रवाह नियंत्रण की स्थिति सभी $?पर्दे के पीछे की जांच करती है; वे यही करते हैं। स्पष्ट रूप से इसके मूल्य की जांच करना अधिकांश मामलों में अनावश्यक होना चाहिए, और आमतौर पर शुरुआती एंटीपैटर्न है।
ट्रिपल एक्स

1
@lunakid यदि आपको निकास कोड की परवाह नहीं है, if ! cmdतो ठीक है। अन्यथा, एक आम व्यवस्था एक elseखंड का उपयोग करना है। आपके पास कोई खाली जगह नहीं हो सकती है thenलेकिन आप कभी-कभी देखते हैं then : nothing; elseकि :नो-ऑप महत्वपूर्ण है। trueवहाँ भी काम करेगा।
ट्रिपलए

47

यह मेरे लिए काम किया:

command && echo "OK" || echo "NOK"

यदि commandसफल होता है, तो echo "OK"निष्पादित किया जाता है, और चूंकि यह सफल है, इसलिए निष्पादन वहीं रुक जाता है। अन्यथा, &&छोड़ दिया जाता है, और echo "NOK"निष्पादित किया जाता है।


5
यदि आप कुछ करना चाहते हैं अगर यह विफल हो जाता है, और बाहर निकलने के कोड को संरक्षित करें (एक स्क्रिप्ट में कमांड प्रॉम्प्ट या टेस्ट में दिखाने के लिए), तो आप यह कर सकते हैं: command && echo "OK" || c=$?; echo "NOK"; $(exit $c)
सैम हसलर

2
@ सैम-हस्लर: क्या ऐसा नहीं होना चाहिए command && echo "OK" || (c=$?; echo "NOK"; (exit $c))?
jrw32982

9
इसके अलावा, यदि echo "OK"भाग स्वयं विफल हो सकता है, तो यह बेहतर है:command && (echo "OK"; exit 0) || (c=$?; echo "NOK"; (exit $c))
jrw32982

@ jrw32982, नाइस, मैंने पूर्व निर्माण का उपयोग किया है, लेकिन बाद का नहीं।
सैम हसलर

असली जवाब टिप्पणियों में है, धन्यवाद!
जोशुआ पिंटर

6

यह ध्यान दिया जाना चाहिए कि / 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

2

सबसे अधिक त्रुटि प्रवण मैं साथ आ सकता था:

  • सबसे पहले, मूल्य प्राप्त करें। मान लीजिए कि आप कुछ ऐसा करते हैं:

RR=$?

अब, न केवल इस स्थिति के लिए, बल्कि अन्य लोग जिनका आप सामना कर सकते हैं, विचार करें:

परिभाषित चर:

$ AA=1 ; if (( "10#0${AA}" == 1 )) ; then echo yes ; else echo no ; fi

उत्तर: हाँ

$ AA=1 ; if (( "10#0${AA}" != 1 )) ; then echo yes ; else echo no ; fi

उत्तर: नहीं

अपरिभाषित चर:

$ AA=1 ; if (( "10#0${BB}" == 1 )) ; then echo yes ; else echo no ; fi

उत्तर: नहीं

$ AA=1 ; if (( "10#0${BB}" != 1 )) ; then echo yes ; else echo no ; fi

उत्तर: हाँ

$ AA=1 ; if (( "10#0${BB}" == 0 )) ; then echo yes ; else echo no ; fi

उत्तर: हाँ

यह सभी प्रकार की त्रुटियों को रोकता है।

आप शायद सभी वाक्यविन्यास से अवगत हैं, लेकिन यहाँ कुछ सुझाव दिए गए हैं:

  • उद्धरण का उपयोग करें। से बचें एक "blank"होने के लिए nothing
  • चरों के लिए नया आधुनिक अंकन है ${variable}
  • अपने नंबर से पहले एक शून्य समाप्‍त जोड़ने से भी "कोई संख्‍या कम नहीं" होती है।
  • लेकिन रुकिए, शून्य जोड़ने से संख्या बन जाती है base-8। आपको एक त्रुटि मिलेगी जैसे:
    • value too great for base (error token is "08")उपरोक्त संख्याओं के लिए 7। कि जब 10#खेल में आता है:
    • 10#होने के लिए संख्या बल base-10

1

तुम यह केर सकते हो:

if ($( ping 4.4.4.4 -c1 > /dev/null )) ; then
  echo "ping response succsess!!!"
fi

9
यह काम करता है लेकिन जटिल है। आप एक उप-प्रकार के उप-भाग में पिंग चला रहे हैं, pingइसे एक कमांड के रूप में चलाने के मद्देनजर कैप्चर किया गया है। लेकिन क्योंकि आउटपुट को / dev / null में रीडायरेक्ट किया जाता है जो हमेशा खाली स्ट्रिंग होगा। तो आप एक सबशेल में कुछ भी नहीं चला रहे हैं, जिसका अर्थ है कि पिछले निकास स्थिति (कमांड प्रतिस्थापन सबस्क्रिप्शन, जो पिंग का है) को बरकरार रखा जाएगा। जाहिर है, सही तरीका if ping ...; thenयहाँ है।
स्टीफन चेज़लस

1

जैसा कि इस सूत्र में कहीं और उल्लेख किया गया है, मूल प्रश्न मूल रूप से स्वयं का उत्तर देता है। यहाँ एक चित्रण दिखाया गया है कि ifस्थितियों को भी नेस्टेड किया जा सकता है।

यह उदाहरण यह ifजाँचने के लिए उपयोग करता है कि क्या कोई फ़ाइल मौजूद है और यदि यह एक नियमित फ़ाइल है। यदि वे स्थितियां सत्य हैं, तो जांचें कि इसका आकार 0 से अधिक है या नहीं।

#!/bin/bash

echo "Which error log are you checking today? "
read answer

if [ -f /opt/logs/$answer*.errors ]
    then
        if [ -s /opt/logs/$answer*.errors ]
            then
                echo "Content is present in the $answer error log file."
            else
                echo "No errors are present in the $answer error log file."
        fi
    else
        echo "$answer does not have an error log at this time."
fi

2
यही आपका उत्तर है, लेकिन आपका उत्तर प्रश्न को संबोधित नहीं करता है।
जेफ स्कालर

@JeffSchaller, आपके नोट के लिए धन्यवाद। मैंने प्रश्न का संदर्भ शामिल करने के लिए अपनी पोस्ट को संपादित किया।
क्वार्ट्जिनक्वार्ट्ज

1
#!/bin/bash

if command-1 ; then
   echo "command-1 succeeded and now running from this block command-2"
   command-2
else
   echo "command-1 failed and now running from this block command-3"
   command-3
fi

3
यह काफी हद तक मौजूदा स्वीकृत उत्तर की तरह दिखता है ; कृपया वह विशेषता कार्य करें जिसका आप पुन: उपयोग कर रहे हैं, या अपने उत्तरों में अपना प्रयास जोड़ें।
जेफ स्कालर

-3

यह केवल इस तरह से किया जा सकता है क्योंकि $?आपको अंतिम निष्पादित स्थिति की स्थिति देता है।

तो यह हो सकता है

#!/bin/sh

... some command ...

if [ $? == 0 ] ; then
  echo '<the output message you want to display>'
else 
  echo '<failure message>'
fi

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