मैं कैसे पता लगा सकता हूं कि गेटटॉप्स के साथ कोई विकल्प पारित नहीं किया गया था।


19

मेरे पास यह कोड है -

#getoptDemo.sh
usage()
{
    echo "usage: <command> options:<w|l|h>"
}
while getopts wlh: option
do
    case $option in
            (w)
                    name='1';;
            (l)
                    name='2';;
            (h)
                    name='3';;
            (*)
                    usage
                    exit;;
    esac
done
print 'hi'$name

जब मैं चला bash getoptDemos.sh(विकल्प के बिना) यह hiफ़ंक्शन को कॉल करने के बजाय प्रिंट करता है usage। W, h और l के अलावा अन्य विकल्प दिए जाने पर यह उपयोग को कॉल करता है। तब यह काम नहीं कर सकता जब कोई विकल्प निर्दिष्ट नहीं किया जाता है।

मैं का उपयोग कर की कोशिश की है ?, \?, :के स्थान पर *, लेकिन मैं हासिल नहीं कर सकते कि मैं क्या करना चाहता था। मैं सब मतलब docsपर getoptकहते हैं कि यह उपयोग करने के लिए ?

मैं क्या गलत कर रहा हूं?


आप इसे किस खोल के नीचे चला रहे हैं?
जूलियन

मैं इसे नीचे चला रहा हूं/bin/bash
हुसैन तंबोली

अन्य विकल्प: wiki.bash-hackers.org/howto/getopts_tutorial
SLM

जवाबों:


15

जब आप इस स्क्रिप्ट को बिना किसी विकल्प के चलाते हैं, तो getopt झूठी वापस आ जाएगी, इसलिए यह लूप में बिल्कुल भी प्रवेश नहीं करेगा। यह सिर्फ प्रिंट के लिए नीचे गिर जाएगा - यह ksh / zsh है?

यदि आपके पास एक विकल्प होना चाहिए, तो आप सबसे अच्छा शर्त है कि लूप के बाद $ नाम का परीक्षण करें।

if [ -z "$name" ]
then
   usage
   exit
fi

लेकिन सुनिश्चित करें $nameकि कॉल करने से पहले खाली था getopts(जैसा $nameकि वातावरण में हो सकता है शेल स्टार्टअप पर प्राप्त हुआ)

unset name

( getoptsलूप से पहले )


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

यदि आप एक अनिवार्य विकल्प चाहते हैं, तो मुझे नहीं लगता कि यह संभव है - शायद इसलिए उन्हें विकल्प कहा जाता है :) आप लूप के बाद यह सुनिश्चित करने के लिए $ नाम का परीक्षण कर सकते हैं कि यह सेट किया गया है। अगर [-z "$ नाम"]; फिर उपयोग; बाहर जाएं ; फाई
जूलियन

धन्यवाद। उपरोक्त कोड ने वास्तव में मदद की। इसका बहुत बुरा getoptsऐसा प्रावधान नहीं है। इससे भी बदतर बात यह है कि आप आगे नहीं बढ़ सकते हैं।
हुसैन तंबोली

क्या होगा अगर मैं अन्य शेल चला रहा हूं? zsh, श। क्या बाश के अलावा कोई खोल इस स्थिति का ख्याल रखता है?
हुसैन तंबोली

20

getoptsबारी में विकल्पों को संसाधित करता है। यही इसका काम है। यदि उपयोगकर्ता बिना किसी विकल्प के पास होता है, तो getoptsलूप से बाहर निकलने का पहला आह्वान होता है।

यदि विकल्पों में से कोई भी तर्क नहीं लेता है, तो यह OPTINDइंगित करता है कि कितने विकल्प पारित किए गए थे। सामान्य तौर पर, OPTINDगैर-तर्क तर्कों (ऑपरेंड) के विपरीत, विकल्पों की संख्या या विकल्पों के तर्क हैं।

while getopts …; do …; done
if [ $OPTIND -eq 1 ]; then echo "No options were passed"; fi
shift $((OPTIND-1))
echo "$# non-option arguments"

किसी भी स्थिति में, आप यह निर्धारित करने की कोशिश नहीं कर रहे हैं कि क्या कोई विकल्प नहीं था, लेकिन क्या कोई भी nameविकल्प समाप्त नहीं हुआ था। इसलिए जांच लें कि nameक्या कोई परेशान है (और पहले इसे शुरू करने का ख्याल रखें)


1
धन्यवाद। आपके लिए +1। जब मैं नमूने में अपने कोड से अंतिम 3 लाइनें डालती हूं । तो bash sample.sh -abc file.txtइसे चलाएं - 1 non-option arguments। मुझे कैसे पता चलेगा कि कितने विकल्प दिए गए थे। (यहाँ 3)
हुसैन तम्बोली

1
अजीब बात है किसी ने भी इस मामूली बग पर टिप्पणी नहीं की है - यदि कोई विकल्प नहीं दिया गया है, तो OPTIND 1 होगा उसके बाद 'गेटटॉप्स ... लूप। इस प्रकार यदि चेक को 1 के साथ समानता की जांच करनी चाहिए, शून्य की नहीं।
डैनियल

4

यदि आपकी स्क्रिप्ट को विकल्प तर्क प्राप्त करने हैं तो किसी भी मामले में, इस ब्लॉक को शुरुआत में (गेटअप से पहले) रखें।

if [[ ! $@ =~ ^\-.+ ]]
then
  #display_help;
fi

ब्लॉक चेक करता है कि पैरामीटर स्ट्रिंग -प्रतीक से शुरू नहीं होती है , जो इंगित करता है कि पहला पैरामीटर एक विकल्प तर्क नहीं है।


2

मैं इसे एक चर के साथ जाँच करूँगा। यदि गेटअप बिना किसी तर्क के मामले में लूप को कभी भी पास नहीं करता है, तो आप उदाहरण के लिए इसका उपयोग कर सकते हैं:

#getoptDemo.sh
usage()
{
    echo "usage: <command> options:<w|l|h>"
}

no_args="true"
while getopts wlh: option
do
    case $option in
            (w)
                    name='1';;
            (l)
                    name='2';;
            (h)
                    name='3';;
            (*)
                    usage
                    exit;;
    esac
    no_args="false"
done

[[ "$no_args" == "true" ]] && { usage; exit 1; }

print 'hi'$name

0

अपने getoptsब्लॉक से ठीक पहले , यह देखने के लिए जांचें कि क्या $1(कमांड लाइन पर आपके द्वारा दिया गया पहला तर्क / विकल्प) खाली स्ट्रिंग के बराबर है। यदि यह है, तो उपयोग संदेश और बाहर निकलें, और (यदि आप एक अराजकतावादी हैं) कुछ "कोई विकल्प नहीं" फ़ंक्शन निष्पादित करें, अन्यथा getoptsसामान्य जैसे विकल्पों को पार्स करें।

इस सुविधा को गेटअप में शामिल नहीं किया गया है, इसका कारण यह है कि आप पहले से ही इसे "if-else" के साथ बैश में पूरा कर सकते हैं। उदाहरण:

if [[ $1 == "" ]]; then
    Your_Usage_Function;
    exit;
else
   #parse options with getopts code block here;
fi

सही बात?

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