2012-07-31 12 views
35

मैं कुछ स्क्रिप्ट के लिए एक रैपर के रूप में एक खोल स्क्रिप्ट डिज़ाइन करना चाहता हूं। मैं के लिए getopts का उपयोग कर पैरामीटर निर्दिष्ट करना चाहता हूं और निर्दिष्ट पैरामीटर को उसी क्रम में निर्दिष्ट स्क्रिप्ट में पास कर दूंगा।शैल स्क्रिप्ट: पोजिशनल पैरामीटर के साथ गेटोपेट मिश्रण कर रहा है?

तो myshell.sh तरह क्रियान्वित किया जाता है:

myshell.sh -h hostname -s test.sh -d waittime param1 param2 param3 

myshell.sh param1 param2 -h hostname param3 -d waittime -s test.sh 

myshell.sh param1 -h hostname -d waittime -s test.sh param2 param3 

सब के सब से ऊपर कॉल करने के लिए के रूप में

test.sh param1 param2 param3 

यह संभवmyshell.shऔर बाद में विकल्प मापदंडों का उपयोग करने में सक्षम होना चाहिए है अंतर्निहित स्क्रिप्ट के लिए शेष पैरामीटर?

+0

तुम क्या करने कोशिश कर रहे हैं? आप 'myshell.sh' में' test.sh param1 param2 param3' को कॉल करना चाहते हैं? –

+0

क्षमा करें अगर यह प्रश्न से स्पष्ट नहीं है। हाँ। मैं अपनी स्क्रिप्ट को पोजिशनल पैरामीटर और गेटोपेट मानों के मिश्रण को संभालने के लिए सक्षम करना चाहता हूं। Getopt से शेष सब कुछ अंतर्निहित खोल स्क्रिप्ट के साथ पारित किया जाना चाहिए। – SiB

+1

केवल पहली पंक्ति विकल्प प्रसंस्करण के लिए यूनिक्स मानकों (नीचे देखें) के अनुरूप है। इसे अन्यथा करना सही होने और बनाए रखने के लिए बहुत अधिक काम होगा। –

उत्तर

65

एक पुराने धागा पर टिप्पणी के लिए क्षमा करें, लेकिन सोचा था कि मैं उन, मेरे जैसे जो ऐसा करने के तरीके पर खोज कर रहे थे के लिए पोस्ट करेंगे ...

मैं ओ पी के लिए इसी तरह कुछ करना चाहता था, और मैं तो फिर इस तरह अपने विकल्पों को मिल

script.sh [options] ARG1 ARG2 

:

01 प्रासंगिक जानकारी मैं here और here

अनिवार्य रूप से अगर आप की तरह कुछ करना चाहता हूँ

आवश्यक पाया

while getopts "h:u:p:d:" flag; do 
case "$flag" in 
    h) HOSTNAME=$OPTARG;; 
    u) USERNAME=$OPTARG;; 
    p) PASSWORD=$OPTARG;; 
    d) DATABASE=$OPTARG;; 
esac 
done 

और फिर आप इस तरह अपने स्थितीय तर्क प्राप्त कर सकते हैं:

ARG1=${@:$OPTIND:1} 
ARG2=${@:$OPTIND+1:1} 

अधिक जानकारी और विवरण ऊपर के लिंक के माध्यम से उपलब्ध हैं।

आशा है कि मदद करता है !!

+24

लेकिन यह स्थितित्मक तर्कों को झंडे से पहले अनुमति नहीं देता है, जो ओपी प्रश्न का हिस्सा था। स्थिति/बाद/झंडे को संभालने का एक और मानक तरीका केवल अपने एएसएसी के बाद $ ((OPTIND-1) को स्थानांतरित करना है और फिर सामान्य रूप से स्थिति को संभालना है। – Chinasaur

+1

@ चाइनासौर जब मैंने 'ARG1 = $ {@: $ OPTIND: 1} 'का उपयोग किया, तब यह मेरे लिए' script.sh -h localhost abc' और' script.sh abc -h localhost' = ARG1 I में दोनों के लिए काम किया। दोनों मामलों में मूल्य 'abc' था। क्या आप अधिक विशिष्ट हो सकते हैं जो काम नहीं कर रहा है (जिसे मैंने गलत समझा)? धन्यवाद! – Betlista

+0

मुझे 'ARG1' नहीं मिल रहा है। यह खाली है। – Sigur

3

getoptsparam1 और -n विकल्पों के मिश्रण को पार्स नहीं करेगा।

param1-3 को दूसरों की तरह विकल्पों में रखना बेहतर है।

इसके अलावा आप shflags जैसे पहले से ही मौजूदा पुस्तकालयों का उपयोग कर सकते हैं। यह बहुत स्मार्ट है और इसका उपयोग करना आसान है।

और आखिरी तरीका अपने स्वयं के फ़ंक्शन को गेट्स के बिना पैरा पार्स पर लिखना है, बस case निर्माण के माध्यम से सभी पैराम को फिर से भरना। यह सबसे कठिन तरीका है लेकिन आपकी अपेक्षाओं से मेल खाने का यही एकमात्र तरीका है।

[संपादित करें: निश्चित दो लिखने की त्रुटियों]

+0

धन्यवाद। जिस तरह से मैंने यहां चुना है वह पार्स 'गेटोप्स' पैरामीटर है और फिर 'शिफ्ट' और पैरामीटर को अंतर्निहित स्क्रिप्ट में पास करता है। – SiB

0

यूनिक्स विकल्प प्रसंस्करण के लिए कुछ मानक हैं, और खोल प्रोग्रामिंग में, getopts उन्हें लागू करने के लिए सबसे अच्छा तरीका है। लगभग किसी भी आधुनिक भाषा (पर्ल, पायथन) में getopts पर एक संस्करण है।

यह सिर्फ एक त्वरित उदाहरण है:

command [ options ] [--] [ words ] 
  1. प्रत्येक विकल्प एक पानी का छींटा, - से प्रारंभ होना चाहिए, और एक एकल चरित्र से मिलकर चाहिए।

  2. GNU परियोजना शुरू की लांग विकल्प, दो डैश --, एक पूरे शब्द, --long_option द्वारा पीछा के साथ शुरू। एएसटी केएसएच प्रोजेक्ट में एक गेटोपेट है जो में एक डैश, - के साथ शुरू होने वाले लंबे विकल्प, और लंबे विकल्प का समर्थन करता है।

  3. विकल्प तर्कों की अपेक्षा कर सकते हैं या नहीं भी कर सकते हैं।

  4. कोई भी शब्द एक पानी का छींटा, -, विकल्प प्रसंस्करण खत्म हो जाएगा के साथ शुरू नहीं।

  5. स्ट्रिंग -- को छोड़ दिया जाना चाहिए और विकल्प प्रसंस्करण खत्म हो जाएगा।

  6. कोई भी शेष तर्क स्थितित्मक पैरामीटर के रूप में छोड़ा गया है।

ओपन समूह पर Utility Argument Syntax

एरिक रेमंड की यूनिक्स विकल्प पत्र और उनके अर्थ के लिए पारंपरिक यूनिक्स विकल्पों पर has a chapter प्रोग्रामिंग की कला एक वर्ग है।

1

मैं एक ही रास्ता है कि सही मायने में getopts मिश्रण करने के लिए विकल्पों और स्थितीय मापदंडों बढ़ाया जा सकता है सोचा। विचार getopts बुला और फिर ओ पी के मामले में n1 पाया किसी भी स्थितीय मापदंडों n2, n3, आदि .:

parse_args() { 
    _parse_args 1 "[email protected]" 
} 

_parse_args() { 
    local n="$1" 
    shift 

    local options_func="$1" 
    shift 

    local OPTIND 
    "$options_func" "[email protected]" 
    shift $((OPTIND - 1)) 

    if [ $# -gt 0 ]; then 
     eval test -n \${n$n+x} 
     if [ $? -eq 0 ]; then 
      eval n$n="\$1" 
     fi 

     shift 
     _parse_args $((n + 1)) "$options_func" "[email protected]" 
    fi 
} 

बताए के बीच वैकल्पिक करने के लिए है, आप इसे पसंद इस्तेमाल कर सकते हैं:

main() { 
    local n1='' n2='' n3='' 
    local duration hostname script 

    parse_args parse_main_options "[email protected]" 

    echo "n1 = $n1" 
    echo "n2 = $n2" 
    echo "n3 = $n3" 
    echo "duration = $duration" 
    echo "hostname = $hostname" 
    echo "script = $script" 
} 

parse_main_options() { 
    while getopts d:h:s: opt; do 
     case "$opt" in 
      d) duration="$OPTARG" ;; 
      h) hostname="$OPTARG" ;; 
      s) script="$OPTARG" ;; 
     esac 
    done 
} 

main "[email protected]" 

इसे चलाने से आउटपुट दिखाता है:

$ myshell.sh param1 param2 -h hostname param3 -d waittime -s test.sh 
n1 = param1 
n2 = param2 
n3 = param3 
duration = waittime 
hostname = hostname 
script = test.sh 

बस अवधारणा का सबूत है, लेकिन शायद यह उपयोगी है कोई व्यक्ति।

नोट: वहाँ एक पकड़ लिया है एक समारोह एक और समारोह parse_argsऔर का उपयोग करता है कॉल parse_args का उपयोग करता है बाहरी समारोह जैसे वाणी यदिlocal n4='', लेकिन भीतरी एक नहीं और 4 या अधिक स्थितीय मापदंडों भीतरी समारोह

1

बस एक जल्दी, जो आसानी से विकल्प और स्थितीय-मानकों (केवल स्थितीय-पैरामीटर छोड़ने का एक मिश्रण संभालती अप मसले को पास किया जाता $ में @):

#!/bin/bash 
while [ ${#} -gt 0 ];do OPTERR=0;OPTIND=1;getopts "p:o:hvu" arg;case "$arg" in 
     p) echo "Path: [$OPTARG]" ;; 
     o) echo "Output: [$OPTARG]" ;; 
     h) echo "Help"    ;; 
     v) echo "Version"   ;; 
    \?) SET+=("$1")           ;; 
    *) echo "Coding error: '-$arg' is not handled by case">&2 ;; 
esac;shift;[ "" != "$OPTARG" ] && shift;done 
[ ${#SET[@]} -gt 0 ] && set "" "${SET[@]}" && shift 

echo -e "=========\nLeftover (positional) parameters (count=$#) are:" 
for i in `seq $#`;do echo -e "\t$i> [${!i}]";done 

नमूना उत्पादन:

[[email protected]:~]$ ./test.sh 'aa bb' -h -v -u -q 'cc dd' -p 'ee ff' 'gg hh' -o ooo 
Help 
Version 
Coding error: '-u' is not handled by case 
Path: [ee ff] 
Output: [ooo] 
========= 
Leftover (positional) parameters (count=4) are: 
     1> [aa bb] 
     2> [-q] 
     3> [cc dd] 
     4> [gg hh] 
[[email protected]:~]$ 
+1

यह एकल "-abc" तर्क में कई विकल्पों को संयोजित करने की अनुमति नहीं देता है। –

1

मिक्स चुनता है और आर्ग:

ARGS="" 
echo "options :" 
while [ $# -gt 0 ] 
do 
    unset OPTIND 
    unset OPTARG 
    while getopts as:c: options 
    do 
    case $options in 
      a) echo "option a no optarg" 
        ;; 
      s) serveur="$OPTARG" 
        echo "option s = $serveur" 
        ;; 
      c) cible="$OPTARG" 
        echo "option c = $cible" 
        ;; 
     esac 
    done 
    shift $((OPTIND-1)) 
    ARGS="${ARGS} $1 " 
    shift 
done 

echo "ARGS : $ARGS" 
exit 1 

परिणाम:

bash test.sh -a arg1 arg2 -s serveur -c cible arg3 
options : 
option a no optarg 
option s = serveur 
option c = cible 
ARGS : arg1 arg2 arg3 
0

आप इस चाल की कोशिश कर सकते हैं: के बाद, जबकि optargs साथ पाश, बस इस टुकड़ा

#shift away all the options so that only positional agruments 
#remain in [email protected] 

for ((i=0; i<OPTIND-1; i++)); do 
    shift 
done 

POSITIONAL="[email protected]" 

हालांकि उपयोग करते हैं, इस दृष्टिकोण एक बग है:

    सभी पहले पोजिशनल तर्क के बाद विकल्प गेटोपेट्स द्वारा दर्ज किए जाते हैं और उन्हें स्थितित्मक तर्क के रूप में माना जाता है - ईवेंट जो सही हैं (नमूना आउटपुट देखें: -एम और -सी स्थितित्मक तर्कों में से हैं)

भी अधिक कीड़े शायद यह है ... पूरे उदाहरण पर

देखो:

while getopts :abc opt; do 
    case $opt in 
     a) 
     echo found: -a 
     ;; 
     b) 
     echo found: -b 
     ;; 
     c) 
     echo found: -c 
     ;; 
     \?) echo found bad option: -$OPTARG 
     ;; 
    esac 
done 

#OPTIND-1 now points to the first arguments not beginning with - 

#shift away all the options so that only positional agruments 
#remain in [email protected] 

for ((i=0; i<OPTIND-1; i++)); do 
    shift 
done 

POSITIONAL="[email protected]" 

echo "positional: $POSITIONAL" 

आउटपुट:

[[email protected] ~]# ./abc.sh -abc -de -fgh -bca haha blabla -m -c 
found: -a 
found: -b 
found: -c 
found bad option: -d 
found bad option: -e 
found bad option: -f 
found bad option: -g 
found bad option: -h 
found: -b 
found: -c 
found: -a 
positional: haha blabla -m -c