具有如下 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