यदि बैश शेल में कई लाइनों पर स्थिति


19

मेरे पास एक बैश शेल फ़ंक्शन है जो एक तर्क लेता है और यदि आवश्यक हो तो उस पर कुछ करता है।

do_somthing() {
  if [need to do something on $1]
  then
    do it
    return 0
  else
    return 1
  fi
}

मैं इस पद्धति को कई तर्कों के साथ कॉल करना चाहता हूं और जांचता हूं कि उनमें से कम से कम एक सफल हुई।

मैंने कुछ इस तरह की कोशिश की:

if [ do_something "arg1" ||
     do_something "arg2" ||
     do_something "arg3" ]
then
  echo "OK"
else
  echo "NOT OK"
fi

उसके लिए सही सिंटैक्स क्या होगा?
EDIT
Also - मैं यह सुनिश्चित करना चाहता हूं कि भले ही पहली शर्त सही हो लेकिन अन्य सभी स्थितियों का मूल्यांकन अभी भी किया जाएगा।

धन्यवाद,


मैंने अपना उत्तर अपडेट कर दिया है।
tectux

धन्यवाद, क्या आप कृपया एक उदाहरण प्रदान कर सकते हैं?
इत्ते

1
मैंने अपने उत्तर में एक कोड उदाहरण जोड़ा है।
tectux

जवाबों:


7

पहले कमांड चलाएं, फिर जांच लें कि उनमें से कम से कम एक सफल हुआ या नहीं।

#!/bin/bash

success=0
do_something arg1 && success=1
do_something arg2 && success=1
do_something arg3 && success=1

if ((success)); then
    printf 'Success! At least one of the three commands succeeded\n'
fi

3
यह भ्रामक है, मुझे खुशी होगी यदि आप कुछ विवरण प्रदान कर सकते हैं कि कैसे सशर्त वक्तव्य बाश में काम करते हैं ..., do_something सफलता पर 0 देता है, लेकिन फिर हम सफलता को 1 में अपडेट करते हैं ... if ((success))से कुछ भिन्न का मूल्यांकन करता है if success। मैं उलझन में हूं :)
Itay

2
@ ((...))यह एक अंकगणित कमांड है। यदि परिणाम अंदर है, तो गैर-शून्य है, यह सच (0) देता है। यदि परिणाम 0 के अंदर है, तो यह गलत है (1)। "सफलता" को एक चर के रूप में माना जाता है जो एक संख्या को शामिल करने की अपेक्षा करता है। देखें mywiki.wooledge.org/ArithmeticExpression
geirha

धन्यवाद, मुझे लगता है कि जो हिस्सा मुझे भ्रमित करता है वह यह है कि 0 सच है और 1 गलत है आमतौर पर यह विपरीत है :)
Itay

2
@ यह हाँ, यह पहली बार में भ्रामक हो सकता है। बैश सामान्य प्रयोजन की भाषाओं से अलग है, क्योंकि यह "कमांड आधारित" है; यह फ़ंक्शन को कॉल नहीं करता है, इसमें कक्षाएं और विधियां नहीं हैं, यह कमांड चलाता है, और कमांड के निकास की स्थिति का परीक्षण करता है। और सी, पाइथन, जावा, पर्ल, आदि भाषाओं की तुलना में बैश में कमांड चलाना बहुत आसान है। सिग्नल सफलता के लिए 0 से बाहर निकलता है, और विभिन्न प्रकार की विफलताओं के लिए 1-255। (एक आदेश आम तौर पर केवल एक तरह से सफल हो सकता है, लेकिन विभिन्न अलग-अलग कारणों से विफल हो सकता है)
गीरा

2
इस समाधान का लाभ है कि आप उन पंक्तियों पर टिप्पणी कर सकते हैं जिन्हें आप अस्थायी रूप से निष्क्रिय नहीं करना चाहते हैं
जोशिया योडर

31

बैकस्लैश का उपयोग करें।

if [ $(do_something "arg1") ] || \
   [ $(do_something "arg2") ] || \
   [ $(do_something "arg3") ]
then
  echo "OK"
else
  echo "NOT OK"
fi

संपादित करें

इसके अलावा - मैं यह सुनिश्चित करना चाहता हूं कि भले ही पहली शर्त सही हो लेकिन अन्य सभी स्थितियों का मूल्यांकन अभी भी किया जाएगा।

केवल एक बयान में यह संभव नहीं है। इसके बजाय आप एक लूप के लिए उपयोग कर सकते हैं जो तर्कों पर आधारित होता है और उनका अलग-अलग मूल्यांकन करता है। कुछ इस तरह:

do_something() {
  for x in "$@"
  do
    if [need to do something on $x]
    then
      do it
    else
      echo "no action required on $x"
    fi
  done
}

धन्यवाद, यह कोशिश की - मुझे एक त्रुटि मिलती है[: do_something: unary operator expected
Itay

क्या आपने प्रत्येक मूल्यांकन को अपने स्वयं के ब्रैकेट के बीच रखा था? इसलिए [ expr1 ] || [ expr2 ]इसके बजाय [ expr1 || expr2 ]
tectux

हां, मैंने किया: (...
इत्ते

मेरा अनुमान है कि do_something "arg1"इसकी व्याख्या दो तर्कों के रूप में की जाती है जबकि अभिव्यक्ति एकात्मक होनी चाहिए। बनाने के किसी भी तरीके का do_something "arg1"मूल्यांकन एक तर्क के रूप में किया जाता है?
इत्ते

1
आप सही हे। यह भी काम करता है if [ $(do_something "arg1") ]:।
tectux

5

सही सिंटैक्स है:

if  do_something "arg1" || \
    do_something "arg2" || \
    do_something "arg3"
then
  echo "OK"
else
  echo "NOT OK"
fi

\ यह बताने के लिए प्रयोग किया जाता है कि शेल अगली पंक्ति में जारी है।

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

#!/bin/bash

do_something() {
  if [need to do something on $1]
  then
    do it
    echo "OK"
  else
    echo "NOT OK"
  fi
}

do_something "arg1"
do_something "arg2"
do_something "arg3"

धन्यवाद, एक त्रुटि के साथ परिणाम:[: too many arguments
Itay

@ यह उत्तर अपडेट किया गया।
एरिक कार्वाल्हो

प्रश्न को अद्यतन करना - यह अभी तक अंतिम उत्तर नहीं है :(
Itay

-1

मैं पसंद करता हूं:

if {
    do_something "arg1" ||
    do_something "arg2" ||
    do_something "arg3"
}; then
    echo "OK"
else
    echo "NOT OK"
fi

आप स्क्रिप्ट बिल्कुल भी काम नहीं करेंगे: 1 परीक्षण पैरामीटर के बाद, यह एक \nचरित्र उत्पन्न करेगा , इसलिए आपका ifकथन कुछ त्रुटियों को उत्पन्न करेगा, और do_somethingनामों को कमांड नहीं कर रहा है, इसलिए अधिक त्रुटियां
दमादम

मेरे लिए यह zsh और bash में काम करता है, IF do_somethingएक कोर्स है। do_somethingफ़ंक्शन या कमांड होना चाहिए, और क्या होना चाहिए? इसके अलावा मैं नहीं देखता कि यह \nपरिणाम
गूँजने के
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.