डनो के बारे में, getopt
लेकिन getopts
बिलिन का उपयोग इस तरह के केवल लंबे विकल्पों को संभालने के लिए किया जा सकता है:
while getopts :-: o
do case "$o$OPTARG" in
(-longopt1) process ;;
(-longopt2) process ;;
esac; done
बेशक, जैसा कि है, अगर लंबे विकल्प के तर्क होने चाहिए तो काम नहीं करता। यह किया जा सकता है, हालांकि, लेकिन, जैसा कि मैंने इस पर काम करना सीख लिया है। जबकि मैंने शुरू में इसे यहाँ शामिल किया था मुझे एहसास हुआ कि लंबे समय के विकल्प के लिए इसकी बहुत अधिक उपयोगिता नहीं है। इस मामले में यह केवल case
(match)
एक एकल, अनुमानित चरित्र द्वारा मेरे क्षेत्रों को छोटा कर रहा था । अब, मुझे जो पता है, वह यह है कि यह छोटे विकल्पों के लिए उत्कृष्ट है - यह सबसे उपयोगी है जब यह अज्ञात लंबाई की एक स्ट्रिंग पर लूप कर रहा है और इसके विकल्प-स्ट्रिंग के अनुसार सिंगल बाइट्स का चयन कर रहा है। लेकिन जब विकल्प है आर्ग, वहाँ आप एक साथ कर रहे हैं एक बहुत नहीं है for var do case $var in
संयोजन यह कर सकता है। यह बेहतर है, मुझे लगता है, इसे सरल रखने के लिए।
मुझे संदेह है कि यह सच है, getopt
लेकिन मैं किसी भी निश्चितता के साथ कहने के लिए पर्याप्त नहीं जानता। जो evalation / असाइनमेंट संबंध मैं के लिए सराहना करने के लिए आए हैं पर मुख्य रूप से निर्भर करता है - निम्नलिखित आर्ग सरणी को देखते हुए, मैं अपने खुद के छोटे से आर्ग पार्सर का प्रदर्शन करेंगे alias
और $((shell=math))
।
set -- this is ignored by default --lopt1 -s 'some '\''
args' here --ignored and these are ignored \
--alsoignored andthis --lopt2 'and
some "`more' --lopt1 and just a few more
यही arg string है जिसके साथ मैं काम करूंगा। अभी:
aopts() { env - sh -s -- "$@"
} <<OPTCASE 3<<\OPTSCRIPT
acase() case "\$a" in $(fmt='
(%s) f=%s; aset "?$(($f)):";;\n'
for a do case "$a" in (--) break;;
(--*[!_[:alnum:]]*) continue;;
(--*) printf "$fmt" "$a" "${a#--}";;
esac;done;printf "$fmt" '--*' ignored)
(*) aset "" "\$a";;esac
shift "$((SHIFT$$))"; f=ignored; exec <&3
OPTCASE
aset() { alias "$f=$(($f${1:-=$(($f))+}1))"
[ -n "${2+?}" ] && alias "${f}_$(($f))=$2"; }
for a do acase; done; alias
#END
OPTSCRIPT
यह दो अलग-अलग तरीकों में से एक में आर्ग सरणी को संसाधित करता है, इस पर निर्भर करता है कि आप इसे एक या दो सेट के तर्क से अलग करते हैं --
। दोनों ही मामलों में यह arg array में प्रोसेसिंग के क्रम पर लागू होता है।
यदि आप इसे कहते हैं:
: $((SHIFT$$=3)); aopts --lopt1 --lopt2 -- "$@"
व्यवसाय का पहला क्रम ऐसा acase()
दिखने के लिए अपना कार्य लिखना होगा :
acase() case "$a" in
(--lopt1) f=lopt1; aset "?$(($f)):";;
(--lopt2) f=lopt2; aset "?$(($f)):";;
(--*) f=ignored; aset "?$(($f)):";;
(*) aset "" "$a";;esac
और बगल में shift 3
। acase()
फ़ंक्शन परिभाषा में कमांड-प्रतिस्थापन का मूल्यांकन तब किया जाता है जब कॉलिंग शेल फ़ंक्शन-इनपुट को यहां-दस्तावेजों में बनाता है, लेकिन acase()
कॉलिंग शेल में कभी भी कॉल या परिभाषित नहीं होता है। यह, हालांकि, निश्चित रूप से, और इस तरह से आप कमांड लाइन पर ब्याज के विकल्प को गतिशील रूप से निर्दिष्ट कर सकते हैं।
यदि आप इसे एक अन-सीमांकित सरणी के रूप में सौंपते हैं तो यह acase()
स्ट्रिंग के साथ शुरू होने वाले सभी तर्कों के लिए मेल खाता है --
।
यह फ़ंक्शन व्यावहारिक रूप से सब-प्रोसेस में सब-शेल में करता है - क्रमिक रूप से सहयोगी नामों के साथ असाइन किए गए उपनामों के प्रत्येक आर्ग के मूल्यों को सहेजना। जब यह इसके माध्यम से होता है तो इसके साथ सहेजे गए हर मूल्य alias
को प्रिंट करता है - जो कि इस तरह से उद्धृत सभी सहेजे गए मूल्यों को प्रिंट करने के लिए POSIX- निर्दिष्ट है ताकि उनके मूल्यों को खोल में फिर से जोड़ा जा सके। इसलिए जब मैं ...
aopts --lopt1 --lopt2 -- "$@"
इसका आउटपुट इस तरह दिखता है:
...ignored...
lopt1='8'
lopt1_1='-s'
lopt1_2='some '\'' args'
lopt1_3='here'
lopt1_4='and'
lopt1_5='just'
lopt1_6='a'
lopt1_7='few'
lopt1_8='more'
lopt2='1'
lopt2_1='and
some "`more'
जैसा कि यह arg सूची के माध्यम से चलता है यह एक मैच के लिए केस ब्लॉक के खिलाफ जांच करता है। यदि यह एक मैच पाता है तो यह एक झंडा फेंकता है - f=optname
। जब तक यह एक बार फिर से एक वैध विकल्प नहीं ढूंढता, तब तक यह प्रत्येक बाद के arg को एक सरणी में जोड़ेगा, जो वर्तमान ध्वज के आधार पर बनाता है। यदि एक ही विकल्प कई बार परिणाम यौगिक निर्दिष्ट किया जाता है और ओवरराइड नहीं करता है। मामले में कुछ भी नहीं - या नजरअंदाज विकल्पों के बाद किसी भी तर्क - एक नजरअंदाज सरणी को सौंपा है ।
शेल द्वारा इनपुट-इनपुट स्वचालित रूप से शेल के लिए आउटपुट सुरक्षित है, और इसी तरह:
eval "$(: $((SHIFT$$=3));aopts --lopt1 --lopt2 -- "$@")"
... पूरी तरह से सुरक्षित होना चाहिए। यदि यह किसी भी कारण से सुरक्षित नहीं है , तो आपको संभवतः अपने शेल अनुचर के साथ बग रिपोर्ट दर्ज करनी चाहिए।
यह प्रत्येक मैच के लिए दो प्रकार के अन्य मान प्रदान करता है। सबसे पहले, यह एक ध्वज सेट करता है - यह तब होता है जब कोई विकल्प गैर-मिलान तर्क से पहले होता है या नहीं। --flag
अर्ग सूची में कोई भी घटना ट्रिगर हो जाएगी flag=1
। यह यौगिक नहीं है - --flag --flag --flag
बस हो जाता है flag=1
। यह मान हालांकि वृद्धि करता है - किसी भी तर्क के लिए जो इसका पालन कर सकता है। इसका उपयोग इंडेक्स की के रूप में किया जा सकता है। eval
ऊपर करने के बाद मैं कर सकता हूँ:
printf %s\\n "$lopt1" "$lopt2"
...लेना...
8
1
इसलिए:
for o in lopt1 lopt2
do list= i=0; echo "$o = $(($o))"
while [ "$((i=$i+1))" -le "$(($o))" ]
do list="$list $o $i \"\${${o}_$i}\" "
done; eval "printf '%s[%02d] = %s\n' $list"; done
आउटपुट
lopt1 = 8
lopt1[01] = -s
lopt1[02] = some ' args
lopt1[03] = here
lopt1[04] = and
lopt1[05] = just
lopt1[06] = a
lopt1[07] = few
lopt1[08] = more
lopt2 = 1
lopt2[01] = and
some "`more
और यह बताने के लिए कि मैं उपर्युक्त क्षेत्र में नजरअंदाज किए जाने वाले विकल्प से मेल नहीं खाता for ... in
:
ignored = 10
ignored[01] = this
ignored[02] = is
ignored[03] = ignored
ignored[04] = by
ignored[05] = default
ignored[06] = and
ignored[07] = these
ignored[08] = are
ignored[09] = ignored
ignored[10] = andthis
getopts
, लेकिन आप/usr/bin/getopt
कमांड का उपयोग कर रहे हैं ।