बैश फंक्शन से बूलियन लौटाना


211

मैं एक बैश फ़ंक्शन लिखना चाहता हूं जो यह जांचता है कि किसी फ़ाइल में कुछ गुण हैं या सही या गलत है। फिर मैं इसे "अगर" में अपनी स्क्रिप्ट में उपयोग कर सकता हूं। लेकिन मैं क्या लौटाऊं?

function myfun(){ ... return 0; else return 1; fi;}

तो मैं इसे इस तरह से उपयोग करता हूं:

if myfun filename.txt; then ...

बेशक यह काम नहीं करता है। इसे किस तरह पूर्ण कर सकते है?


3
functionकीवर्ड ड्रॉप करें , myfun() {...}पर्याप्त
ग्लेन जैकमैन

2
ifशून्य-निकास स्थिति के लिए क्या मायने रखता है myfun: यदि myfunबाहर निकलता है 0, then ...तो निष्पादित किया जाता है; अगर यह कुछ और else ... है तो निष्पादित किया जाता है।
आठवीं

7
@nhed: functionकीवर्ड एक बैशीवाद है, और कुछ अन्य गोले में वाक्यविन्यास त्रुटियों का कारण होगा। मूल रूप से, यह या तो अनावश्यक या निषिद्ध है, इसलिए इसका उपयोग क्यों करें? यह grep लक्ष्य के रूप में भी उपयोगी नहीं है, क्योंकि यह नहीं हो सकता है ( ()इसके बजाय grep )।
गॉर्डन डेविसन

3
@GordonDavisson: क्या? अन्य गोले हैं? ;-)
1'13

कृपया 0 का उपयोग न करें और 1. देखें stackoverflow.com/a/43840545/117471
ब्रूनो ब्रोंस्की

जवाबों:


333

सत्य के लिए 1 और झूठ के लिए 1 का उपयोग करें।

नमूना:

#!/bin/bash

isdirectory() {
  if [ -d "$1" ]
  then
    # 0 = true
    return 0 
  else
    # 1 = false
    return 1
  fi
}


if isdirectory $1; then echo "is directory"; else echo "nopes"; fi

संपादित करें

@ अमीचिर की टिप्पणी से, ये भी संभव हैं

isdirectory() {
  if [ -d "$1" ]
  then
    true
  else
    false
  fi
}


isdirectory() {
  [ -d "$1" ]
}

4
नहीं, आपको ऐसा करने की आवश्यकता नहीं है - नमूना देखें।
एरिक

46
बेहतर पठनीयता के लिए आप 'सही' कमांड का उपयोग कर सकते हैं (जो कुछ भी नहीं करता है और सफलतापूर्वक पूरा करता है, यानी 0 देता है) और 'गलत' कमांड (जो कुछ भी नहीं करता है और असफल रूप से पूरा होता है, अर्थात गैर-शून्य मान लौटाता है)। इसके अलावा, एक फ़ंक्शन जो स्पष्ट रिटर्न स्टेटमेंट के बिना समाप्त होता है, अंतिम निष्पादित कमांड का निकास कोड लौटाता है, इसलिए ऊपर दिए गए उदाहरण में, फ़ंक्शन बॉडी को केवल कम किया जा सकता है [ -d "$1" ]
अमीचैर

24
बेंग्ट: यह समझ में आता है कि आप इसे "त्रुटि कोड" समझते हैं: त्रुटि कोड 0 = सब कुछ ठीक हो गया = 0 त्रुटियां; त्रुटि कोड 1 = मुख्य बात यह थी कि कॉल विफल होना चाहिए था; और: असफल! इसे मैनपेज में देखें।
उड़ान भेड़

7
यह समझ में आता है जब आप समझते हैं कि प्रोग्रामिंग चीजें आमतौर पर केवल एक तरह से सफल हो सकती हैं, लेकिन अनंत तरीकों से विफल हो सकती हैं। खैर शायद अनंत नहीं, लेकिन बहुत सारे, बाधाओं हमारे खिलाफ खड़ी हैं। सफलता / त्रुटि (बों) बूलियन नहीं है। मुझे लगता है कि यह "सच के लिए 0 और झूठ के लिए 1 का उपयोग करें।" "सफलता के लिए 0 और विफलता के लिए गैर-शून्य का उपयोग करें" पढ़ना चाहिए।
दावोस

6
कृपया 0 का उपयोग न करें और 1. देखें stackoverflow.com/a/43840545/117471
ब्रूनो ब्रोंस्की

167

आपको इस बात की परवाह क्यों करनी चाहिए कि मैं 250+ अपवोट उत्तर होने के बावजूद क्या कहता हूं

ऐसा नहीं है कि नहीं है 0 = trueऔर 1 = false। यह है: शून्य का मतलब है कोई विफलता (सफलता) और गैर-शून्य का मतलब विफलता (प्रकार एन)

जबकि चयनित उत्तर तकनीकी रूप से "सत्य" है, कृपया झूठेreturn 1 के लिए ** अपने कोड में न डालें । इसके कई दुर्भाग्यपूर्ण दुष्प्रभाव होंगे।

  1. अनुभवी डेवलपर्स आपको एक शौकिया के रूप में देखेंगे (नीचे दिए गए कारण के लिए)।
  2. अनुभवी डेवलपर्स ऐसा नहीं करते हैं (नीचे दिए गए सभी कारणों के लिए)।
  3. यह त्रुटि प्रवण है।
    • यहां तक ​​कि अनुभवी डेवलपर्स क्रमशः 0 और 1 को गलत और सच मान सकते हैं (ऊपर दिए गए कारण के लिए)।
  4. इसके लिए विलक्षण और हास्यास्पद टिप्पणियों की आवश्यकता होती है (या प्रोत्साहित करेंगे)।
  5. यह वास्तव में निहित रिटर्न की स्थिति से कम सहायक है।

जानें कुछ बैश

बैश मैनुअल का कहना है (जोर मेरा)

वापसी [एन]

एक शेल फ़ंक्शन को निष्पादित करने से रोकने और उसके कॉलर को मान n वापस करने के लिए कारण। यदि n की आपूर्ति नहीं की जाती है , तो रिटर्न वैल्यू फ़ंक्शन में निष्पादित अंतिम कमांड की निकास स्थिति है

इसलिए, हमें True और False को इंगित करने के लिए 0 और 1 का उपयोग करने की आवश्यकता नहीं है। तथ्य यह है कि वे ऐसा करते हैं अनिवार्य रूप से तुच्छ ज्ञान केवल डिबगिंग कोड, साक्षात्कार के सवालों के लिए उपयोगी है, और newbies के दिमाग को उड़ाने।

बैश मैनुअल भी कहता है

अन्यथा फ़ंक्शन की वापसी स्थिति निष्पादित अंतिम कमांड की निकास स्थिति है

बैश मैनुअल भी कहता है

( $? ) सबसे हाल ही में निष्पादित अग्रभूमि पाइपलाइन की निकास स्थिति का विस्तार करता है ।

वाह, रुको। पाइप लाइन? चलो बैश मैनुअल को एक बार फिर चालू करें

एक पाइप लाइन एक या एक से अधिक कमांड का एक अनुक्रम है जिसे नियंत्रण ऑपरेटरों में से एक द्वारा अलग किया जाता है। ' या '| &'।

हाँ। उन्होंने कहा कि 1 कमांड एक पाइपलाइन है। इसलिए, उन उद्धरणों में से 3 एक ही बात कह रहे हैं।

  • $? आपको बताते हैं कि आखिर हुआ क्या था।
  • यह बुदबुदाता है।

मेरा जवाब

इसलिए, जबकि @Kambus ने प्रदर्शित किया कि इस तरह के एक सरल कार्य के लिए, returnबिल्कुल भी कोई आवश्यकता नहीं है। मुझे लगता है कि ज्यादातर लोग जो इसे पढ़ेंगे, उनकी जरूरतों की तुलना में अनुचित रूप से सरल था।

क्यों return?

यदि कोई फ़ंक्शन अपने अंतिम कमांड के निकास की स्थिति को वापस करने जा रहा है, तो returnसभी का उपयोग क्यों करें ? क्योंकि यह एक फ़ंक्शन को निष्पादित करने से रोकता है।

कई शर्तों के तहत निष्पादन बंद करो

01  function i_should(){
02      uname="$(uname -a)"
03
04      [[ "$uname" =~ Darwin ]] && return
05
06      if [[ "$uname" =~ Ubuntu ]]; then
07          release="$(lsb_release -a)"
08          [[ "$release" =~ LTS ]]
09          return
10      fi
11
12      false
13  }
14
15  function do_it(){
16      echo "Hello, old friend."
17  }
18
19  if i_should; then
20    do_it
21  fi

हमारे यहाँ क्या है ...

लाइन 04एक स्पष्ट [-इश] सच है क्योंकि एलएचएस सच होने पर &&केवल आरएचएस निष्पादित हो जाता है

लाइन 09की स्थिति से मेल खाते हुए या तो सही या गलत है08

लाइन के 13कारण लाइन झूठी हो जाती है12

(हाँ, यह नीचे गोल्फ हो सकता है, लेकिन पूरे उदाहरण से वंचित है।)

एक और आम पैटर्न

# Instead of doing this...
some_command
if [[ $? -eq 1 ]]; then
    echo "some_command failed"
fi

# Do this...
some_command
status=$?
if ! $(exit $status); then
    echo "some_command failed"
fi

ध्यान दें कि एक statusचर की स्थापना कैसे अर्थ को नष्ट करती है $?। (निश्चित रूप से आप जानते हैं कि $?इसका क्या मतलब है, लेकिन किसी को आप से कम जानकार किसी दिन Google को देना होगा। जब तक कि आपका कोड उच्च आवृत्ति व्यापार नहीं कर रहा है, तब तक कुछ प्यार दिखाएं , चर सेट करें।) लेकिन असली टेक- ऑफ यह है कि "अगर स्थिति मौजूद नहीं है "या इसके विपरीत" अगर बाहर निकलने की स्थिति है "ज़ोर से पढ़ा जा सकता है और उनका अर्थ समझा सकता है। हालाँकि, यह अंतिम एक बहुत ही महत्वाकांक्षी हो सकता है क्योंकि शब्द exitको देखने से आपको लग सकता है कि यह स्क्रिप्ट से बाहर निकल रहा है, जब वास्तव में यह $(...)सबमिशन से बाहर निकल रहा है ।


** यदि आप return 1असत्य के लिए उपयोग करने के लिए पूरी तरह से जोर देते हैं , तो मैं आपको return 255इसके बजाय कम से कम उपयोग करने का सुझाव देता हूं । यह आपके भविष्य के स्वयं, या किसी भी अन्य डेवलपर का कारण होगा, जिसे आपके कोड को "यह 255 क्यों है?" तब वे कम से कम ध्यान दे रहे होंगे और गलती से बचने का बेहतर मौका होगा।


1
झूठ और सच के लिए @ZeroPhase 1 & 0 हास्यास्पद होगा। यदि आपके पास बाइनरी डेटाटाइप है, तो उसके लिए कोई कारण नहीं है। आप किस चीज से टकरा रहे हैं, एक स्थिति कोड है जो सफलता (एकवचन) और असफलता (बहुवचन) को दर्शाता है। यह " ifसफलता यह करो, elseवह करो।" सफलता किस पर? सत्य / असत्य की जाँच हो सकती है, एक स्ट्रिंग, पूर्णांक, फ़ाइल, निर्देशिका के लिए जाँच की जा सकती है, अनुमतियाँ, ग्लोब, regex, grep, या कोई अन्य कमांड जो विफलताओं के अधीन है
ब्रूनो ब्रॉन्स्की

3
0/1 के मानक उपयोग को रिटर्न वैल्यू के रूप में केवल इसलिए टालना क्योंकि यह बहुत ही कठिन है और भ्रम की स्थिति है। पूरी शैल भाषा अप्रिय है और भ्रम की स्थिति है। बैश स्वयं trueऔर falseआदेशों में 0/1 = सही / गलत सम्मेलन का उपयोग करता है । अर्थात्, कीवर्ड trueशाब्दिक रूप से 0 स्थिति कोड का मूल्यांकन करता है। इसके अलावा, अगर-तब प्रकृति द्वारा बयान बुलियन पर काम करते हैं, सफलता कोड नहीं। यदि बूलियन ऑपरेशन के दौरान कोई त्रुटि होती है, तो यह सही या गलत नहीं होनी चाहिए, लेकिन बस निष्पादन को तोड़ दें। अन्यथा आपको झूठी सकारात्मकता (सजा) मिलती है।
बीजोर

1
"अगर! $ ($ स्थिति से बाहर); तो" - यह एक बेहतर स्पष्टीकरण का हकदार है। यह सहज नहीं है। मुझे इस बारे में सोचना होगा कि क्या संदेश प्रिंट करने से पहले प्रोग्राम बाहर निकल जाएगा या नहीं। आपके उत्तर का बाकी हिस्सा अच्छा था, लेकिन इसने इसे खराब कर दिया।
क्रेग हिक्स

1
@BrunoBronosky मैंने आपका उत्तर पढ़ा और मुझे लगता है कि मैं सामग्री पाइपलाइन (स्टड-> स्टडआउट) और रिटर्न मानों में त्रुटि कोड के बीच अंतर को समझता हूं। फिर भी, मुझे समझ नहीं आ रहा है कि क्यों प्रयोग करने return 1से बचना चाहिए। मान लें कि मेरे पास एक validateफ़ंक्शन है, तो मुझे यह उचित लगता है return 1यदि सत्यापन विफल हो जाता है। आखिरकार, यह एक स्क्रिप्ट के निष्पादन को रोकने का एक कारण है अगर इसे ठीक से संभाला नहीं जाता है (जैसे, उपयोग करते समय set -e)।
जेपीजेड

1
@ जेपज़ यह एक महान प्रश्न है। आप सही हैं जो return 1मान्य है। मेरी चिंता यहाँ सभी टिप्पणियों को कह रही है "0 = सच 1 = गलत है [नकारात्मक शब्द डालें]"। उन लोगों को किसी दिन आपके कोड को पढ़ने की संभावना है। तो उन्हें देखने के लिए return 255(या 42 या 2) उन्हें इसके बारे में अधिक सोचने में मदद करनी चाहिए और इसे "सच" के रूप में गलत नहीं करना चाहिए। set -eअभी भी इसे पकड़ लेंगे।
बजे ब्रूनो ब्रोंस्की

31
myfun(){
    [ -d "$1" ]
}
if myfun "path"; then
    echo yes
fi
# or
myfun "path" && echo yes

1
उपेक्षा के बारे में क्या?
einpoklum

इसके बारे में, @einpoklum क्या है?
मार्क रीड

@MarkReed: मेरा मतलब है, अपने उदाहरण में "और" मामला जोड़ें।
ईनपोकलुम

myfun "पथ" || इको नं
ह्राबकी

13

केवल विकल्प -d के साथ निर्देशिका की जाँच करते समय सावधान रहें!
अगर वेरिएबल $ 1 खाली है तो चेक फिर भी सफल होगा। सुनिश्चित करने के लिए, यह भी जांचें कि चर खाली नहीं है।

#! /bin/bash

is_directory(){

    if [[ -d $1 ]] && [[ -n $1 ]] ; then
        return 0
    else
        return 1
    fi

}


#Test
if is_directory $1 ; then
    echo "Directory exist"
else
    echo "Directory does not exist!" 
fi

1
मैं अनिश्चित हूं कि यह पूछे गए सवाल का जवाब कैसे देता है। हालांकि यह जानना अच्छा है कि एक खाली $ 1 खाली होने पर एक सच्चा रिटर्न दे सकता है, यह किसी भी फंक्शन को सही या गलत तरीके से वापस करने के बारे में कोई जानकारी प्रदान नहीं करता है। मैं एक नया प्रश्न बनाने का सुझाव दूंगा "जब आप एक खाली शेल चर पर एक परीक्षण करते हैं तो क्या होता है?" और फिर इस जवाब के रूप में पोस्टिंग।
DRAehal

3
ध्यान दें, यदि आप उचित उद्धरण जोड़ते हैं $1( "$1") तो आपको एक खाली चर की जांच करने की आवश्यकता नहीं है। यह [[ -d "$1" ]]विफल होगा क्योंकि यह ""एक निर्देशिका नहीं है।
मुर्गे

3

मुझे एक बिंदु का सामना करना पड़ा (अभी तक उल्लेख नहीं किया गया है?) जिस पर मैं लड़खड़ा गया था। यही है, बूलियन को वापस नहीं करना है, बल्कि इसका सही मूल्यांकन कैसे करें!

मैं कहना चाह रहा था if [ myfunc ]; then ..., लेकिन यह गलत है। आपको कोष्ठक का उपयोग नहीं करना चाहिए! if myfunc; then ...इसे करने का तरीका है।

पर जैसा कि @Bruno और दूसरों को दोहराया, trueऔर falseकर रहे हैं आदेशों , नहीं महत्व देता है! शेल स्क्रिप्ट में बुलियन को समझना बहुत महत्वपूर्ण है।

इस पोस्ट में, मैंने बूलियन वेरिएबल्स का उपयोग करके समझाया और बताया : https://stackoverflow.com/a/55174008/3220483 । मैं दृढ़ता से यह जाँचने का सुझाव देता हूँ, क्योंकि यह बहुत निकट से संबंधित है।

यहाँ, मैं फ़ंक्शंस से बूलियनों के लौटने और मूल्यांकन के कुछ उदाहरण प्रदान करूँगा :

यह:

test(){ false; }                                               
if test; then echo "it is"; fi                                 

कोई प्रतिध्वनि उत्पादन नहीं करता है। (यानी गलत false रिटर्न )

test(){ true; }                                                
if test; then echo "it is"; fi                                 

पैदा करता है:

it is                                                        

(यानी सही true रिटर्न )

तथा

test(){ x=1; }                                                
if test; then echo "it is"; fi                                 

पैदा करता है:

it is                                                                           

क्योंकि 0 (यानी सच) को स्पष्ट रूप से वापस कर दिया गया था ।

अब, यह वही है जो मुझे परेशान कर रहा था ...

test(){ true; }                                                
if [ test ]; then echo "it is"; fi                             

पैदा करता है:

it is                                                                           

तथा

test(){ false; }                                                
if [ test ]; then echo "it is"; fi                             

ALSO का उत्पादन:

it is                                                                           

यहाँ कोष्ठक के प्रयोग से एक झूठी सकारात्मकता उत्पन्न हुई ! (मुझे "बाहरी" कमांड परिणाम 0. है।)

मेरी पोस्ट से प्रमुख लेना यह है: एक बूलियन फ़ंक्शन (या चर) का मूल्यांकन करने के लिए कोष्ठक का उपयोग न करें जैसे कि आप एक सामान्य समानता की जांच करेंगे जैसे if [ x -eq 1 ]; then...!


2

trueया falseपहले अपने कमांड का प्रयोग करें return, फिर returnबिना किसी पैरामीटर के। returnस्वचालित रूप से अपने पिछले आदेश के मूल्य का उपयोग होगा।

returnयदि आप 1 या 0. का उपयोग नहीं कर रहे हैं तो त्रुटि के लिए तर्क असंगत, टाइप विशिष्ट और प्रवण प्रदान करना है और जैसा कि पिछली टिप्पणियों में कहा गया है, यहां 1 या 0 का उपयोग करना इस फ़ंक्शन का दृष्टिकोण करने का सही तरीका नहीं है।

#!/bin/bash

function test_for_cat {
    if [ $1 = "cat" ];
    then
        true
        return
    else
        false
        return
    fi
}

for i in cat hat;
do
    echo "${i}:"
    if test_for_cat "${i}";
    then
        echo "- True"
    else
        echo "- False"
    fi
done

आउटपुट:

$ bash bash_return.sh

cat:
- True
hat:
- False

1

यदि आप इसे इस function myfun(){ ... return 0; else return 1; fi;}रूप में लिखते हैं तो यह काम कर सकता है function myfun(){ ... return; else false; fi;}। यह है कि यदि falseफ़ंक्शन में अंतिम निर्देश है तो आपको पूरे फ़ंक्शन के लिए गलत परिणाम मिलता है, लेकिन returnवैसे भी सच्चे परिणाम के साथ फ़ंक्शन को बाधित करता है। मेरा मानना ​​है कि यह मेरे बैश दुभाषिया के लिए कम से कम सच है।


1

मैंने पाया कि फ़ंक्शन आउटपुट का परीक्षण करने के लिए सबसे छोटा रूप बस है

do_something() {
    [[ -e $1 ]] # e.g. test file exists
}

do_something "myfile.txt" || { echo "File doesn't exist!"; exit 1; }

1

कोड पठनीयता कारणों के लिए मेरा मानना ​​है कि सही / गलत लौटना चाहिए:

  • एक लाइन पर हो
  • एक आज्ञा हो
  • याद रखना आसान है
  • returnकिसी अन्य कीवर्ड के बाद कीवर्ड का उल्लेख करें ( trueया false)

मेरा समाधान है return $(true)या return $(false)जैसा दिखाया गया है:

is_directory()
{
    if [ -d "${1}" ]; then
        return $(true)
    else
        return $(false)
    fi
}

0

@ ब्रूनो ब्रोंस्की और @ आर्टटाइम पर आने के बाद, मैं सुझाव देता हूं कि आप अपना बूलियन रिटर्न "बैकवर्ड" लिखें। मेरा मतलब यह है:

foo()
{
    if [ "$1" == "bar" ]; then
        true; return
    else
        false; return
    fi;
}

कि हर वापसी बयान के लिए बदसूरत दो लाइन की आवश्यकता को समाप्त करता है।

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