簡體   English   中英

在bash腳本的getopts中不允許多個選項

[英]not allow multiple option in getopts of bash script

具有以下bash腳本

#! /bin/bash

usage()
{
  echo -e "need help!"  
}

while getopts ":a:b:h" OPTION
do
     case $OPTION in
     a)
        printf "a option with value %s\n" $OPTARG
        ;;
     b)
        printf "b option with value %s\n" $OPTARG
        ;;
     h)
        usage
        ;;
     ?)
        echo -e "No option selected"
       ;;
    esac
done

exit 0

上面的腳本可以使用其他選項很好地運行,但是我想擴展它以不允許同時傳遞多個選項,例如以下參數

$ ./test.bash -a 1 -b 2
a option with value 1
b option with value 2

應該是無效的,這意味着它以某種方式給我帶來錯誤,例如wrong syntax我通過以下方式實現了它,但是似乎很長一段時間如下

#! /bin/bash
usage()
{
  echo -e "need help!"  
}

let "a_count=0"
let "b_count=0"
MY_ARG=""
while getopts ":a:b:h" OPTION
do
     case $OPTION in
     a)
        let a_count=1
        MY_ARG=$OPTARG
        ;;
     b)
        let b_count=1
        MY_ARG=$OPTARG
        ;;
     h)
        usage
        ;;
     ?)
        echo -e "No option selected"
       ;;
    esac
done

[[ $a_count -eq 1 ]] && [[ $b_count -eq 1 ]] && echo "wrong command sytax" && exit 0

[[ $a_count -eq 1 ]] &&  printf "a option with value %s\n" $MY_ARG

[[ $b_count -eq 1 ]] &&  printf "b option with value %s\n" $MY_ARG

exit 0

$ ./test.bash -a 1 -b 2
wrong command sytax

但是我想在while..loopgetopts完成驗證。 此外,此驗證不適用於以下命令

./test.bash -a -b 
a option with value -b

任何人都有想法如何使用getopts進行這種類型驗證嗎?

你差不多了。 :在一個后和B之后說,他們采取的參數,所以你的榜樣-a -b實際上是有效的,說:“有是選項與值-B”。

如果您真的只想要“ -a或-b然后一個參數”,則可能根本不需要getopts,但應該這樣做:

[ "$1" == "-a" ] && printf "a option with value %s\n" $2
[ "$1" == "-b" ] && printf "b option with value %s\n" $2

任何人都有想法如何使用getopts進行這種類型驗證嗎?

好吧,實際上,您是在明確告訴geptopts -a-b不是布爾參數,而是帶有額外參數的參數。 參數解析器無法分辨-a的參數是參數還是它自己的參數,因此他們將[-a] [-b]視為語法。

最好的方法實際上是當您不希望為-a-b使用參數時,使用不同的布爾參數來匹配用例。

雖然,嘗試使用自變量或布爾值作為參數對您的問題沒有幫助,但是對於自變量語法檢查,您可以嘗試docopt ,它具有一種更好的創建命令行界面的方法。 您專注於--help文檔,它將對其進行解析以構建參數/參數解析器。 例如:

eval "$(docopts -V - -h - : "$@" <<EOF
Usage: myscript [(-a <foo> | -b <bar> | -abool | -bbool)]

      -a <foo>   The A option.
      -b <bar>   The B option.
      -abool     The A bool
      -bbool     The B bool
      --help     Show help options.
      --version  Print program version.
----
myscript 0.0.0
Copyright (C)20.. Your Name
License...
)"

if $a ; then
    echo "a option! with $a"
fi

if $b ; then
    echo "b option! with $b"
fi

if $abool ; then 
    echo "abool option!"
fi


if $bbool ; then 
    echo "bbool option!"
fi

這不是很完美,因為它將始終處理第一個開關,但是確實在while循環中放置了一個出口,這符合您的設計要求。 它可能會給您一個如何完成它的想法。

#!/bin/bash

usage()
{
  echo -e "need help!"
}

while getopts "a:b:h" OPTION
do
     case $OPTION in
     a)
       aflag=1
       aval=$OPTARG
       if [ ! -z "$bflag" ]
       then
         printf "ERROR: cant use both -a and -b\n"
         exit 1
       fi
       ;;
    b)
       bflag=1
       bval=$OPTARG
       if [ ! -z "$aflag" ]
       then
        printf "ERROR: cant use both -a and -b\n"
        exit 1
       fi
       ;;
    h) usage ;;
    ?) printf "ERROR" ; exit 1 ;;
   esac
done

if [ ! -z "$aflag" ]
then    
  printf "a option with value %s $aval\n"
elif [ ! -z "$bflag" ]
then
  printf "b option with value %s $bval\n"
fi

exit 0

如果仍然要使用getopts我將使用bash內置變量作為參數count $#來檢測傳遞的參數數量錯誤:

#! /bin/bash

usage()
{
  echo -e "need help!"  
}

# Check if number of arguments is greater than 2 as "-a1" (one arg) and "-a 2" are correct.
# You might want to check for other wrong inputs.
if [ $# > 2 ]
then
    echo "Some warning t o the user or"
    usage
    exit 1
fi

while getopts ":a:b:h" OPTION
do
     case $OPTION in
     a)
        printf "a option with value %s\n" $OPTARG
        ;;
     b)
        printf "b option with value %s\n" $OPTARG
        ;;
     h)
        usage
        ;;
     ?)
        echo -e "No option selected"
       ;;
    esac
done

exit 0

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM