繁体   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