किसी शर्त के विफल होने पर बैश स्क्रिप्ट को कैसे रोकें?


11

यहाँ यह कमांड के निष्पादन को समाप्‍त करने के लिए ||और &&एक ही पंक्ति में उपयोग करने के लिए दिखाता है : मैं कैसे bash स्क्रिप्ट में apt-get त्रुटियाँ देख सकता हूँ?

मैं एक स्क्रिप्ट निष्पादन को रोकने की कोशिश कर रहा हूं यदि एक निश्चित स्थिति विफल हो जाती है,

जैसे

false || echo "Obvious error because its false on left" && exit

यहां यह प्रिंट करता है Obvious error because its false on the leftऔर कंसोल को बाहर निकालता है जो कि मैं चाहता था।

true || echo "This shouldn't print" && exit

यहाँ, कोई इको प्रिंट नहीं है, लेकिन exitकमांड भी चलता है, अर्थात, कंसोल बंद है, exitकमांड चलना नहीं चाहिए क्योंकि दाईं ओर इको कमांड निष्पादित नहीं किया गया था? या डिफ़ॉल्ट रूप से एक बयान को एक &&ऑपरेटर के बाएं हाथ पर गलत माना जाता है ?

संपादित करें: मुझे पहले इसका उल्लेख करना चाहिए था, मेरा उद्देश्य त्रुटि को प्रतिध्वनित करना और बाहर निकलना था यदि यह स्पष्ट नहीं था। गलतियों को पकड़ने के मेरे विशिष्ट मामले के लिए wrt जब && का उपयोग करके स्थितियां समूहित की जाती हैं और @, @ bodhi.zazen उत्तर समस्या को हल करता है।

@takatakatek उत्तर प्रवाह नियंत्रण के बारे में अधिक स्पष्ट बनाता है और बैश गाइड लिंक उत्कृष्ट हैं

@ muru के उत्तर में इस बात की अच्छी व्याख्या है कि सेट-ई का उपयोग क्यों न करें यदि आप चाहते हैं कि कस्टम त्रुटि संदेश पर्ल और ट्रैप के उपयोग के विकल्पों के साथ फेंके जाएं जो मुझे लगता है कि एक अधिक मजबूत तरीका है और खुद को मेरी दूसरी बैश स्क्रिप्ट से इसका उपयोग करते हुए देखें!


जहां तक ​​मैं बता सकता हूं कि यह स्क्रिप्ट से बाहर हो गया है।
पैंथर

जवाबों:


10

आप शायद चाहते हैं (जैसा कि स्टीलड्राइवर ने बताया)

true || { echo "This shouldn't print" && exit; }

अन्यथा आपकी स्क्रिप्ट एक समय में एक सशर्त पढ़ रही है

एक या बी और फिर बाहर निकलें

मुझे लगता है कि आप या (बी और निकास) चाहते हैं?


4
दरअसल, आपको (जैसा कि @steeldriver ने सुझाव दिया है) का उपयोग करना चाहिए{ ... ; } , या फिर exitकेवल सबस्क्रिप्शन से बाहर निकलता है, और पेरेंट शेल स्क्रिप्ट को निष्पादित करना जारी रखता है।
गॉर्डन डेविसन

14

समस्या यह है कि || और जब स्थिति विफल हो जाती है, तो केवल && केवल एक कमांड श्रृंखला के एक बाद के श्लोक को छोड़ दें। यदि आप एक पूर्ण ब्लॉक संरचना लिखते हैं तो यह सही समझ में आता है। आपने जो लिखा है वह इस प्रकार है:

if ! true ; then
   echo "This shouldn't print"
else
   exit
fi

आप यह क्या चाहते हैं:

if ! true ; then
   echo "This shouldn't print"
   exit
fi

जब आप बैश के शॉर्टकट सशर्त ऑपरेटरों का उपयोग कर रहे हैं तो उन्हें मिश्रण करने से बचना बेहतर है। तर्क को समझना बहुत आसान है जबकि आप इसे लिख रहे हैं, और आपके पाठक आपकी अच्छी शैली की सराहना करेंगे।


2
हां मेरी राय में यह बहुत अधिक है कि कैसे बाश में कंडीशनिंग लिखा जाना चाहिए
derHugo

@takatakatek यह अधिक स्पष्ट करता है कि यह मेरे मामले में विफल क्यों है। मैं इस बात से सहमत हूं कि इसमें तर्क स्पष्ट है, लेकिन && और || सशर्त बयानों का उपयोग करके उन्हें व्यक्त करने से बचना है?
कोसोल

@kosol हाँ, और& और || दो चीजों को मिलाएं: पिछली कमांड की निकास स्थिति का परीक्षण करना, और एक कमांड (या कमांड समूह) को निष्पादित (के लिए &&) या स्किड (के लिए) निर्दिष्ट करना। वे बहुत ही सरल मामलों के लिए उपयोगी हो सकते हैं, लेकिन वे पूरी तरह से व्यक्त if ... then ... elif ... else ... fiब्लॉकों को प्रतिस्थापित नहीं कर सकते हैं । मुझे संदेह है कि आप इस बात से अवगत नहीं होंगे कि बैश में अधिक परिष्कृत भाषाओं में देखे गए सच्चे बूलियन प्रकार नहीं हैं। यदि कमांड की निकास स्थिति 0 (शून्य) है, तो बैश उसे सही / सफल मानता है । यदि निकास की स्थिति गैर-शून्य है, तो बैश उसे गलत / असफल मानता है ।
टेकटकटेक

7

त्रुटि पर विफल होने का सबसे सरल तरीका है बैश के -eविकल्प ( set -eया /bin/bash -eशेलबैंग में) का उपयोग करना। हालाँकि, इससे कस्टम त्रुटि संदेश भेजना आसान नहीं होता है। कुछ मुहावरे हैं जो इसे सरल बना सकते हैं:

die आ ला पर्ल

पर्ल के पास एक बहुत ही सुविधाजनक dieकमांड है जो संदेश को stderr पर प्रिंट करता है और एक अपवाद उठाता है, जो आमतौर पर स्क्रिप्ट को समाप्त करने की ओर जाता है। आप इसका अनुकरण कर सकते हैं:

die () {
  ret=$?
  print "%s\n" "$@" >&2
  exit "$ret"
}

false || die "Obvious error because its false on left"
true || die "This shouldn't print"

trap ERR

trap <command>आदेश, एक कमांड को चलाने के लिए जब एक संकेत प्राप्त किया जा सकता है या जब स्क्रिप्ट (बाहर निकलने trap ... EXITके लिए एक कमांड), या जब एक त्रुटि देता है ( trap ... ERR)। तो कुछ इस तरह:

trap 'ret=$?; printf "%s\n" "$ERR_MSG" >&2; exit "$ret"' ERR

फिर:

ERR_MSG="Obvious error because its false here"
false
ERR_MSG="This shouldn't print"
true

किसी भी स्थिति में, मैं यह exit 1बताने का सुझाव दूंगा कि स्क्रिप्ट विफल हो गई है । एक सादा exitपिछली कमांड के निकास की स्थिति का उपयोग करेगा, जो इन मामलों में echoया printfकमांड होगा, जो आमतौर पर सफल होगा। मैंने यहाँ जैसा फेलिंग कमांड का एक्जिट स्टेटस सेव किया है, वह अच्छा होगा।


6

आप स्क्रिप्ट को शुरू करने के साथ थोड़ा प्रयोग करने की कोशिश कर सकते हैं

#!/bin/bash -e

-ई यह सुनिश्चित करता है कि स्क्रिप्ट उस क्षण से बाहर निकल जाए जो कुछ गलत है। एक विशिष्ट विफलता के साथ फिर से बचा जा सकता हैsomething || true

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