getoptऔर getoptsअलग-अलग जानवर हैं, और लोगों को लगता है कि वे जो कुछ करते हैं, उसकी गलतफहमी है। एक लूप में कमांड-लाइन विकल्पों को संसाधित getoptsकरने के bashलिए एक अंतर्निहित कमांड है और अंतर्निहित वेरिएबल्स के बदले में प्रत्येक पाया गया विकल्प और मूल्य असाइन करें, ताकि आप उन्हें आगे प्रोसेस कर सकें। getoptहालाँकि, एक बाहरी उपयोगिता कार्यक्रम है, और यह वास्तव में आपके लिए आपके विकल्पों को संसाधित नहीं करता है जैसे कि बैश getopts, पर्ल Getoptमॉड्यूल या पायथन optparse/ argparseमॉड्यूल करते हैं। वह सब - जो getoptविकल्प पास हो गए हैं, उन्हें कैनोनिकलाइज़ करता है - अर्थात उन्हें अधिक मानक रूप में परिवर्तित करें, ताकि शेल स्क्रिप्ट के लिए उन्हें संसाधित करना आसान हो। उदाहरण के लिए, एक आवेदन getoptनिम्नलिखित को परिवर्तित कर सकता है:
myscript -ab infile.txt -ooutfile.txt
इस मामले में:
myscript -a -b -o outfile.txt infile.txt
आपको वास्तविक प्रसंस्करण स्वयं करना होगा। getoptयदि आप विकल्पों को निर्दिष्ट करने के तरीके पर विभिन्न प्रतिबंध लगाते हैं तो आपको इसका उपयोग करने की आवश्यकता नहीं है :
- केवल एक विकल्प प्रति तर्क;
- सभी विकल्प किसी भी स्थितिगत मापदंडों (यानी गैर-विकल्प तर्क) से पहले जाते हैं;
- मूल्यों के साथ विकल्पों के लिए (जैसे
-oऊपर), मूल्य को एक अलग तर्क (एक स्थान के बाद) के रूप में जाना है।
के getoptबजाय का उपयोग क्यों करें getopts? मूल कारण यह है कि केवल जीएनयू getoptआपको लंबे समय से नामित कमांड-लाइन विकल्पों के लिए समर्थन देता है। 1 (जीएनयू getoptलिनक्स पर डिफ़ॉल्ट है। मैक ओएस एक्स और फ्रीबीएसडी एक बुनियादी और बहुत उपयोगी नहीं है getopt, लेकिन जीएनयू संस्करण स्थापित किया जा सकता है। नीचे देखें।)
उदाहरण के लिए, यहाँ जीएनयू का उपयोग करने का एक उदाहरण है getopt, मेरी एक स्क्रिप्ट से javawrap:
# NOTE: This requires GNU getopt. On Mac OS X and FreeBSD, you have to install this
# separately; see below.
TEMP=`getopt -o vdm: --long verbose,debug,memory:,debugfile:,minheap:,maxheap: \
-n 'javawrap' -- "$@"`
if [ $? != 0 ] ; then echo "Terminating..." >&2 ; exit 1 ; fi
# Note the quotes around `$TEMP': they are essential!
eval set -- "$TEMP"
VERBOSE=false
DEBUG=false
MEMORY=
DEBUGFILE=
JAVA_MISC_OPT=
while true; do
case "$1" in
-v | --verbose ) VERBOSE=true; shift ;;
-d | --debug ) DEBUG=true; shift ;;
-m | --memory ) MEMORY="$2"; shift 2 ;;
--debugfile ) DEBUGFILE="$2"; shift 2 ;;
--minheap )
JAVA_MISC_OPT="$JAVA_MISC_OPT -XX:MinHeapFreeRatio=$2"; shift 2 ;;
--maxheap )
JAVA_MISC_OPT="$JAVA_MISC_OPT -XX:MaxHeapFreeRatio=$2"; shift 2 ;;
-- ) shift; break ;;
* ) break ;;
esac
done
यह आपको जैसे --verbose -dm4096 --minh=20 --maxhe 40 --debugfi="/Users/John Johnson/debug.txt"या समान विकल्प निर्दिष्ट करता है । कॉल के प्रभाव को getoptविकल्पों को स्पष्ट करने के लिए है --verbose -d -m 4096 --minheap 20 --maxheap 40 --debugfile "/Users/John Johnson/debug.txt"ताकि आप उन्हें आसानी से संसाधित कर सकें। आसपास उद्धृत करना "$1"और "$2"महत्वपूर्ण है क्योंकि यह सुनिश्चित करता है कि उनमें रिक्त स्थान वाले तर्क ठीक से संभाले जाएं।
यदि आप पहले 9 लाइनों ( eval setलाइन के माध्यम से सब कुछ ) को हटाते हैं , तो कोड अभी भी काम करेगा ! हालाँकि, यह आपके कोड में अधिक विकल्प होगा कि यह किस प्रकार के विकल्पों को स्वीकार करता है: विशेष रूप से, आपको ऊपर वर्णित "कैनोनिकल" फॉर्म में सभी विकल्पों को निर्दिष्ट करना होगा। के उपयोग के साथ getopt, हालांकि, आप एकल-अक्षर विकल्पों को समूहीकृत कर सकते हैं, लंबे-विकल्पों के छोटे गैर-अस्पष्ट रूपों का उपयोग कर --file foo.txtसकते --file=foo.txtहैं, या तो शैली का उपयोग कर -m 4096सकते -m4096हैं, या तो शैली का उपयोग कर सकते हैं, किसी भी क्रम में विकल्प और गैर-विकल्प का मिश्रण कर सकते हैं, आदि। getoptयदि कोई अपरिचित या अस्पष्ट विकल्प पाए जाते हैं, तो एक त्रुटि संदेश भी आउटपुट करता है।
नोट : वास्तव में , बुनियादी और GNU के दो पूरी तरह से अलग-अलग संस्करण हैं getopt, विभिन्न विशेषताओं और विभिन्न कॉलिंग सम्मेलनों के साथ। 2 मूल काफी टूटा हुआ है: न केवल यह लंबे विकल्पों को संभालता है, यह तर्क या खाली तर्क के अंदर एम्बेडेड रिक्त स्थान को भी नहीं संभाल सकता है, जबकि यह सही करता है। उपरोक्त कोड बेसिक में काम नहीं करेगा । जीएनयू लिनक्स पर डिफ़ॉल्ट रूप से स्थापित है, लेकिन मैक ओएस एक्स और फ्रीबीएसडी पर इसे अलग से स्थापित करने की आवश्यकता है। Mac OS X पर, MacPorts ( http://www.macports.org ) स्थापित करें और फिर GNU (आमतौर पर ) स्थापित करें, और सुनिश्चित करें कि आपके शेल पथ में आगे हैgetoptgetoptgetoptgetoptsgetoptgetoptsudo port install getoptgetopt/opt/local/bin/opt/local/bin/usr/bin। FreeBSD पर, इंस्टॉल करें misc/getopt।
अपने स्वयं के कार्यक्रम के लिए उदाहरण कोड को संशोधित करने के लिए एक त्वरित गाइड: पहले कुछ पंक्तियों के लिए, सभी "बॉयलरप्लेट" है जो कॉल करने वाली रेखा को छोड़कर, समान रहना चाहिए getopt। आपको प्रोग्राम के नाम को बाद में बदलना चाहिए -n, बाद में छोटे विकल्प -oऔर बाद के लंबे विकल्पों को निर्दिष्ट करना चाहिए --long। एक मान लेने वाले विकल्पों के बाद एक कोलन लगाएं।
अंत में, यदि आपको वह कोड दिखाई देता setहै eval set, जिसके बजाय बस है , तो यह बीएसडी के लिए लिखा गया था getopt। आपको इसे eval setशैली का उपयोग करने के लिए बदलना चाहिए , जो दोनों संस्करणों के साथ ठीक काम करता है getopt, जबकि सादे setGNU के साथ सही काम नहीं करता है getopt।
1 वास्तव में, getoptsमें ksh93समर्थन करता है लंबे समय से नामित विकल्प है, लेकिन इस खोल अक्सर के रूप में के रूप में इस्तेमाल नहीं कर रहा है bash। में zsh, zparseoptsइस कार्यक्षमता को प्राप्त करने के लिए उपयोग करें।
2 तकनीकी रूप से, "जीएनयू getopt" एक मिथ्या नाम है; यह संस्करण वास्तव में GNU प्रोजेक्ट के बजाय लिनक्स के लिए लिखा गया था। हालांकि, यह सभी GNU सम्मेलनों का अनुसरण करता है, और "GNU getopt" शब्द का आमतौर पर उपयोग किया जाता है (जैसे FreeBSD पर)।