不允许在 bash 脚本的 getopt 中有多个选项



具有如下 bash 脚本

#! /bin/bash
usage()
{
  echo -e "need help!"  
}
while getopts ":a:b:h" OPTION
do
     case $OPTION in
     a)
        printf "a option with value %sn" $OPTARG
        ;;
     b)
        printf "b option with value %sn" $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 %sn" $MY_ARG
[[ $b_count -eq 1 ]] &&  printf "b option with value %sn" $MY_ARG
exit 0

像一样运行

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

但我想在getopts while..loop完成验证.此外,此验证不适用于以下命令

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

任何人都知道如何使用getopts进行此类型验证吗?

你几乎得到了它。a 后面和 b 后面的:说他们接受一个参数,所以你用 -a -b 的例子实际上是有效的,说"有值为 -b 的选项 a"。

如果你真的只想要"-a 或 -b 然后是一个参数",你可能根本不需要 getopts,但应该这样做:

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

任何人都知道如何使用 getOpt 进行这种类型验证吗?

好吧,实际上,您明确告诉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 -bn"
         exit 1
       fi
       ;;
    b)
       bflag=1
       bval=$OPTARG
       if [ ! -z "$aflag" ]
       then
        printf "ERROR: cant use both -a and -bn"
        exit 1
       fi
       ;;
    h) usage ;;
    ?) printf "ERROR" ; exit 1 ;;
   esac
done
if [ ! -z "$aflag" ]
then    
  printf "a option with value %s $avaln"
elif [ ! -z "$bflag" ]
then
  printf "b option with value %s $bvaln"
fi
exit 0

如果您仍然想使用 getopts 我会使用 bash 内置变量作为参数计数$#来检测传递的错误参数数:

#! /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 %sn" $OPTARG
        ;;
     b)
        printf "b option with value %sn" $OPTARG
        ;;
     h)
        usage
        ;;
     ?)
        echo -e "No option selected"
       ;;
    esac
done
exit 0

相关内容

  • 没有找到相关文章

最新更新