2011-01-03 10 views
18

मुझे पहले से ही गेटोपेट के बारे में पता है, और यह ठीक है, लेकिन यह कष्टप्रद है कि आपको अनिवार्य तर्कों के लिए भी झंडा होना है।तर्कों को लेने वाली बैश स्क्रिप्ट कैसे बनाएं?

आदर्श रूप में, मैं एक स्क्रिप्ट जो इस रूप में तर्क प्राप्त करता है करने के लिए सक्षम होने के लिए करना चाहते हैं:

script.sh [optional arguments] [anything required] 
उदाहरण

script.sh -rvx output_file.txt 

जहां स्क्रिप्ट कहते हैं कि आप एक निर्गम के लिए है

फ़ाइल। क्या ऐसा करने का कोई आसान तरीका है?

जहां तक ​​मुझे पता है, गेटोपेट के साथ इसे देखना होगा: script.sh -rvx -f output_file.txt, और यह बहुत साफ नहीं है।

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

उत्तर

29

इसके द्वारा निर्मित गेटोपेट का उपयोग न करें, इसके बजाय getopt (1) का उपयोग करें। वे (subtly) अलग हैं और अलग-अलग चीजें अच्छी तरह से करते हैं। आप परिदृश्य के लिए आप ऐसा कर सकता है:

#!/bin/bash 

eval set -- $(getopt -n $0 -o "-rvxl:" -- "[email protected]") 

declare r v x l 
declare -a files 
while [ $# -gt 0 ] ; do 
     case "$1" in 
       -r) r=1 ; shift ;; 
       -v) v=1 ; shift ;; 
       -x) x=1 ; shift ;; 
       -l) shift ; l="$1" ; shift ;; 
       --) shift ;; 
       -*) echo "bad option '$1'" ; exit 1 ;; 
       *) files=("${files[@]}" "$1") ; shift ;; 
     esac 
done 

if [ ${#files} -eq 0 ] ; then 
     echo output file required 
     exit 1 
fi 

[ ! -z "$r" ] && echo "r on" 
[ ! -z "$v" ] && echo "v on" 
[ ! -z "$x" ] && echo "x on" 

[ ! -z "$l" ] && echo "l == $l" 

echo "output file(s): ${files[@]}" 

संपादित करें: पूर्णता के लिए मैं एक तर्क की आवश्यकता होती है एक विकल्प से निपटने का एक उदाहरण प्रदान की है।

+0

ऐसा लगता है कि यह वही है जो मैं चाहता हूं। इसके साथ एक सवाल, हालांकि: अगर मैं एक ध्वज की अनुमति देना चाहता हूं जो तर्क लेता है (उदाहरण के लिए, -l file.txt), वाक्यविन्यास क्या होगा? एक बार फिर धन्यवाद। –

+0

इसके लिए गेटोपट मैन पेज से परामर्श लें। संक्षेप में: विकल्प में एक कोलन संलग्न करें (उदा। '" -rv: x "', जिसके लिए तर्क लेने के लिए वी की आवश्यकता होती है)। लंबे विकल्प भी समर्थित हैं, जो एक तरह से गेटोपेट्स को निर्मित करता है। ध्यान दें कि आपको अतिरिक्त गैर-विकल्प तर्क स्वयं को संभालना होगा। – Sorpigal

+0

आपको बहुत बहुत धन्यवाद। एक उत्कृष्ट प्रतिक्रिया। –

11

यदि आप गेट्स का उपयोग कर रहे हैं, तो बस अपने केस स्टेटमेंट के बाद $OPTIND-1 पर स्थानांतरित करें। फिर $* में जो कुछ बचा है, वह सबकुछ होगा, जो शायद आप चाहते हैं।

shift $((${OPTIND} - 1)); echo "${*}" 
+0

यूप। यह सुनिश्चित करने के लिए बस $ # की जांच करें कि आवश्यक तर्कों की सही संख्या पारित की गई थी, फिर उन्हें सामान्य रूप से $ 1, $ 2, आदि के रूप में एक्सेस करें। –

4

आप भ्रम से पीड़ित हैं; getopts का उपयोग करके ध्वज पत्र द्वारा उपसर्ग किए गए अनिवार्य तर्कों की आवश्यकता नहीं होती है। मैंने स्क्रिप्ट के अपने कॉर्पस से एक उपयुक्त उदाहरण खोजने की कोशिश की; यह एक अर्द्ध सभ्य अनुमान है। इसे rcsunco कहा जाता है और इसका उपयोग आरसीएस से चेकआउट रद्द करने के लिए किया जाता है। मैंने इसे थोड़ी देर में संशोधित नहीं किया है, मैं देखता हूं; मैं इसे अक्सर इस्तेमाल करता हूं (क्योंकि मैं आरसीएस से पूरी तरह से माइग्रेट नहीं हुआ हूं)।

#!/bin/sh 
# 
# "@(#)$Id: rcsunco.sh,v 2.1 2002/08/03 07:41:00 jleffler Exp $" 
# 
# Cancel RCS checkout 

# -V print version number 
# -n do not remove or rename checked out file (like SCCS unget) (default) 
# -r remove checked out file (default) 
# -k keep checked out file as $file.keep 
# -g checkout (unlocked) file after clean-up 
# -q quiet checkout 

: ${RCS:=rcs} 
: ${CO:=co} 

remove=yes 
keep=no 
get=no 
quiet= 

while getopts gknqrV opt 
do 
    case $opt in 
    V) echo "`basename $0 .sh`: RCSUNCO Version $Revision: 2.1 $ ($Date: 2002/08/03 07:41:00 $)" | 
     rcsmunger 
     exit 0;; 
    g) get=yes;; 
    k) keep=yes;; 
    n) remove=no;; 
    q) quiet=-q;; 
    r) remove=yes;; 
    *) echo "Usage: `basename $0 .sh` [-{n|g}][-{r|k}] file [...]" 1>&2 
     exit 1;; 
    esac 
done 

shift $(($OPTIND-1)) 

for file in $* 
do 
    rfile=$(rfile $file) 
    xfile=$(xfile $rfile) 
    if $RCS -u $rfile 
    then 
     if [ $keep = yes ] 
     then 
      if [ -f $xfile ] 
      then 
       mv $xfile $xfile.keep 
       echo "$xfile saved in $xfile.keep" 
      fi 
     elif [ $remove = yes ] 
     then rm -f $xfile 
     fi 
     if [ $get = yes ] && [ $remove = yes -o $keep = yes ] 
     then $CO $quiet $rfile 
     fi 
    fi 
done 

यह केवल अर्ध-सभ्य अनुमान है; यदि आप वैकल्पिक तर्कों के बाद कोई फ़ाइल नाम नहीं देते हैं तो स्क्रिप्ट चुपचाप कुछ भी नहीं करती है। हालांकि, अगर आपको इसकी आवश्यकता है, तो आप जांच सकते हैं कि 'शिफ्ट' के बाद अनिवार्य तर्क मौजूद हैं। मेरी एक और लिपि में अनिवार्य तर्क हैं। यह शामिल हैं:

... 
shift $(($OPTIND - 1)) 

case $# in 
2) case $1 in 
    install) MODE=Installation;; 
    uninstall) MODE=Uninstallation;; 
    *)   usage;; 
    esac;; 
*) usage;; 
esac 

तो, कि आदेश (jlss) इस तरह के -d $HOME के रूप में वैकल्पिक तर्क ले जा सकते हैं, लेकिन या तो install या uninstall कुछ स्थापित करने के लिए के नाम के बाद की आवश्यकता है। उपयोग की बुनियादी मोड है:

jlss install program 

लेकिन वैकल्पिक विधा है:

jlss -d $HOME -u me -g mine -x -p install program 

क्योंकि यह बारे में 12 विकल्प हैं मैं jlss के सभी दिखाई नहीं दिया है - यह नहीं rcsunco के रूप में के रूप में कॉम्पैक्ट है ।


आप विकल्प तर्कों से पहले अनिवार्य तर्क के साथ काम कर रहे थे, तो आप थोड़ा और काम करने के लिए होगा:

  • आप अनिवार्य तर्क लेने चाहते हैं, उनमें से बाहर स्थानांतरण मार्ग।
  • फिर आप झंडे के साथ वैकल्पिक तर्कों को संसाधित करते हैं।
  • अंत में, यदि उपयुक्त हो, तो आप अतिरिक्त 'फ़ाइल नाम' तर्कों को संभाल लेंगे।

यदि आप विकल्प तर्क (अनिवार्य दोनों के पहले और बाद में) के साथ अनिवार्य तर्कों से निपट रहे हैं, तो आपके पास अभी भी और अधिक काम है। इसका उपयोग कई वीसीएस सिस्टम द्वारा किया जाता है; सीवीएस और Git दोनों सुविधा है:

git -global option command [-sub option] [...] 

यहाँ, आप वैश्विक विकल्प प्राप्त करने के एक getopts पाश चलाने; अनिवार्य तर्क उठाओ; और सब-विकल्प प्राप्त करने के लिए दूसरा getopts पाश चलाएं (और शायद 'फ़ाइल नाम' तर्कों पर अंतिम लूप चलाएं)।

जीवन मजेदार नहीं है?

2

और मैं एक पूरी तरह से विपरीत बात सुनी है, कि तुम getopt उपयोग नहीं करना चाहिए, लेकिन getopts बिल्टिन।

Cross-platform getopt for a shell script

कभी getopt का उपयोग (1)। Getopt एम्बेडेड व्हाइटस्पेस के साथ खाली तर्क स्ट्रिंग्स, या तर्कों को संभाल नहीं सकता है। कृपया भूलें कि यह कभी भी मौजूद था।

पॉज़िक्स शैल (और अन्य) गेटोपेट प्रदान करते हैं जो का उपयोग करने के लिए सुरक्षित है।

संबंधित मुद्दे