बैश फ़ंक्शन से मान लौटाता है


10

मेरे पास एक फ़ंक्शन है जो 1 रिटर्न देता है यदि संख्या एक वैध दस अंकों की संख्या है:

valNum()
{
    flag=1
    if [[ $1 != [1-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9] ]]; then
        echo "Invalid Number"
        flag=0
    fi
    return $flag
}

यह कहा जा रहा है:

if [[ $(valNum $num) -eq 1 ]]; then
      #do something
fi

यदि फ़ंक्शन मान्य है, तो फ़ंक्शन ठीक काम कर रहा है, लेकिन यदि कोई अमान्य नंबर इनपुट है तो सिंटैक्स त्रुटि दिखा रहा है।

जवाबों:


14

@ चोराबा का उत्तर सही है, हालाँकि यह उदाहरण स्पष्ट हो सकता है:

valNum $num
valNumResult=$? # '$?' is the return value of the previous command
if [[ $valNumResult -eq 1 ]]
then
  : # do something
fi

यह उदाहरण थोड़ा लंबा है ( $valNumResultफिर उस मान को क्वेरी करते हुए), लेकिन अधिक स्पष्ट रूप से वर्णन करता है कि क्या होता है: जो valNum()एक मान लौटाता है, और उस मूल्य को जांचा और परखा जा सकता है।

पुनश्च कृपया अपने आप को एक एहसान करो और वापस जाने 0के लिए trueके लिए और गैर शून्य false। इस तरह से आप विफलता के मामले में "हम असफल क्यों हुए" यह इंगित करने के लिए वापसी मूल्य का उपयोग कर सकते हैं।


8

बैश में कार्य केवल बाहर निकलने के कोड वापस कर सकते हैं। कमांड प्रतिस्थापन, इसके विपरीत, कमांड या फ़ंक्शन के मानक आउटपुट प्राप्त करने के लिए उपयोग किया जाता है। इसलिए, लौटे हुए झंडे की जांच करने के लिए, आपको प्रतिस्थापन की आवश्यकता नहीं है:

if valNum "$num" ; then
    # ...
fi

लेकिन, इसके लिए काम करने के लिए, आपको 0 वापस आ जाना चाहिए यदि संख्या वैध है, और 1 यदि यह नहीं है (निकास कोड 0 का अर्थ है कोई त्रुटि नहीं)।


मुझे नहीं मिला। उदाहरण में 24.7 tldp.org/LDP/abs/html/complexfunct.html में फ़ंक्शन अधिकतम मान लौटा रहा है और निकास कोड नहीं। यद्यपि आपका सुझाव काम कर रहा है, लेकिन मैं यह समझने में सक्षम नहीं हूं कि यह क्यों काम कर रहा है
user2179293

1
चूँकि आपका परीक्षण यह पता लगाना है कि इनपुट वैध 10 अंकों का पूर्णांक है या नहीं, अर्थात सही या गलत है, तो फ़ंक्शन 0 या 1. कोरोबा का उदाहरण देता है, क्योंकि "यदि यह सत्य है" के if valnum "$num"बराबर काम करता है if valnum "$num" = 0। श स्क्रिप्टिंग में अंगूठे का मूल नियम यह है कि 0 = सत्य / सफलता, गैर-शून्य = गलत / त्रुटि।
कैस

2
BTW, कि "एडवांस्ड बैश-स्क्रिप्टिंग गाइड" बहुत अच्छा गाइड नहीं है - यह बहुत सारी चीजों के बारे में गलत है और कुछ खराब स्क्रिप्टिंग प्रथाओं को प्रोत्साहित करता है। mywiki.wooledge.org/BashFAQ पर बैश FAQ अधिक बेहतर संसाधन है।
कैस


आपका कार्य विफल हो रहा है क्योंकि यह स्ट्रिंग "अमान्य संख्या" को प्रतिध्वनित करता है, और आप तब उस स्ट्रिंग और संख्या 1 के बीच एक संख्यात्मक तुलना कर रहे हैंif [[ $(valNum $num) -eq 1 ]]
केस

5

आप शेल फ़ंक्शन से एक मनमाना परिणाम नहीं लौटा सकते। आप केवल एक स्थिति कोड लौटा सकते हैं, जो 0 और 255 के बीच पूर्णांक है। (जब आप किसी बड़े मान को पास कर सकते हैं return, तो यह modulo 256 से छोटा है।) सफलता को इंगित करने के लिए मान 0 होना चाहिए और विफलता को इंगित करने के लिए एक अलग मान; सम्मेलन द्वारा आपको 1 और 125 के बीच त्रुटि कोड से चिपके रहना चाहिए, क्योंकि उच्च मूल्यों का एक विशेष अर्थ है (126 और 127 के लिए खराब बाहरी कमांड, उच्च मूल्यों के लिए एक संकेत द्वारा मारा गया)।

चूंकि आप यहां हां-या-कोई परिणाम नहीं दे रहे हैं, इसलिए एक स्थिति कोड उपयुक्त है। चूंकि flagसफलता या विफलता का संकेत मिलता है, इसलिए आपको सफलता के लिए 0 और असफलता के लिए 1 (आपने जो लिखा है) के पारंपरिक मूल्यों का उपयोग करना चाहिए। आप एक if स्टेटमेंट में सीधे अपने फंक्शन का उपयोग कर सकते हैं।

valNum ()
{
  local flag=0
  if [[ $1 != [1-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9] ]]; then
    echo 1>&2 "Invalid Number"
    flag=1
  fi
  return $flag
}
if valNum "$num"; then
  #do something
fi

यदि आपको विफलता कोड के बीच भेदभाव करने की आवश्यकता है, तो फ़ंक्शन को सीधे कॉल करें। इसके लौटने के तुरंत बाद, विफलता कोड में उपलब्ध है $?। फिर आप इसे केस स्टेटमेंट के साथ देख सकते हैं:

valNum "$num"
case $? in 

यदि आपको बाद में स्थिति कोड का उपयोग करने की आवश्यकता है, तो इसे $?अगले आदेश द्वारा अधिलेखित होने से पहले दूसरे चर में सहेजें ।

valNum "$num"
valNum_status=$?

आपने जो लिखा वह काम नहीं किया क्योंकि कमांड प्रतिस्थापन $(…)फ़ंक्शन के आउटपुट में फैलता है, जो आपके कोड में या तो त्रुटि संदेश है या खाली है, कभी नहीं 1

यदि आपको किसी शेल कोड से स्थिति कोड से अधिक जानकारी पास करने की आवश्यकता है, तो आपके पास दो संभावनाएँ हैं:

  • मानक आउटपुट पर कुछ पाठ प्रिंट करें, और फ़ंक्शन को कमांड प्रतिस्थापन में कॉल करें: $(valNum "$num")
  • फ़ंक्शन के अंदर एक या अधिक चर को असाइन करें और बाद में उन चर को पढ़ें।

2

मेरे पास इस क्षेत्र में अपने आप में परस्पर विरोधी परिणाम हैं। यहाँ मेरे अनुभवजन्य प्रयोगों के परिणाम हैं। सबसे पहले, बैश या * निक्स कमांड के बारे में कुछ ' सिद्धांत ':

  • सफलता == 0 ... अर्थात कोई त्रुटि स्थिति कोड नहीं)
  • विफल! = 0 ...... कुछ स्थिति कोड

उदाहरण:

if  ls -lt /nonexistantdir
then 
    echo "found"
else
    echo "FAIL"
fi
#
echo
ls -lt /nonexistantdir; echo "status = $?"
echo "status = $?"

आउटपुट:

ls: cannot access '/nonexistantdir': No such file or directory
FAIL... 

ls: cannot access '/nonexistantdir': No such file or directory
status = 2

जैसा कि दिखाया गया है, lsकमांड स्टेटस कोड = 2 लौटाता है। जब आप एक वैध निर्देशिका की कोशिश करते हैं, तो स्थिति शून्य ( 0 ) है। लगभग सभी अन्य भाषाओं के समान नहीं।

नियम # 1 - बनाओ ...

  • सत्य ==
  • FALSE! = 0

हमें याद रखना चाहिए कि हम बैश स्टेटमेंट में त्रुटि कोड का परीक्षण कर रहे हैं if। मैं स्थिरांक स्थापित करता हूं, या आप शेल trueया falseकमांड का उपयोग कर सकते हैं ।

TRUE=0
FALSE=1

#  valid number function
#
valNum()
{
    flag=$TRUE

    if [[ $1 != [1-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9] ]]; then
        echo "Invalid Number"
        flag=$FALSE
    fi
    return $flag
}

#    later on ...
#
if validNum Abc 
then
    echo "Lucky number"
else
    echo "Not lucky."
fi

और उत्पादन:

Invalid Number
Not lucky.

हालाँकि, मेरा सुझाव है कि आप किसी भी ' अप-वोट ' @ गाइल्स को दें क्योंकि उसका उत्तर सही है। मैं बस ई-पेपर पर सरलीकृत-साइड को प्राप्त करना चाहता था।

बस एक और बात, testकमान। ऐसा दिखता है:

[[ some-expression ]]; 

सर्वाधिक समय। और उदाहरण के लिए:

$ test 1
$ echo "result = $?"
result = 0
$ test 0
$ echo "result = $?"
result = 0

शून्य (को ०) सच होना । क्यों? वैसे मैन पेज कहता है कि एक भी तर्क ' सही ' है जब वह NOT-NULL है।

संदर्भ:

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