在我的 bash 脚本中,我想用来getopts解析命令行选项。
我的第一次尝试是学习如何使用它,如下:
#!/bin/bash
v_option_arg=""
r_option_arg=""
h_option_arg=""
function get_opt_args() {
while getopts ":v:r:h:" opt
do
case $opt in
"v")
v_option_arg="$OPTARG"
;;
"h")
h_option_arg="$OPTARG"
;;
"r")
r_option_arg="$OPTARG"
;;
"?")
echo "Unknown option -$OPTARG"
exit 1
;;
":")
echo "No argument value for option -$OPTARG"
;;
*)
# Should not occur
echo "Unknown error while processing options"
;;
esac
done
shift $((OPTIND-1))
}
get_opt_args $@
if [ ! -z "$v_option_arg" ]; then
echo "Argnument value for option -v: $v_option_arg"
fi
if [ ! -z "$r_option_arg" ]; then
echo "Argnument value for option -r: $r_option_arg"
fi
if [ ! -z "$h_option_arg" ]; then
echo "Argnument value for option -h: $h_option_arg"
fi
Run Code Online (Sandbox Code Playgroud)
#!/bin/bash
v_option_arg=""
r_option_arg=""
h_option_arg=""
function get_opt_args() {
while getopts ":v:r:h:" opt
do
case $opt in
"v")
v_option_arg="$OPTARG"
;;
"h")
h_option_arg="$OPTARG"
;;
"r")
r_option_arg="$OPTARG"
;;
"?")
echo "Unknown option -$OPTARG"
exit 1
;;
":")
echo "No argument value for option -$OPTARG"
;;
*)
# Should not occur
echo "Unknown error while processing options"
;;
esac
done
shift $((OPTIND-1))
}
get_opt_args $@
if [ ! -z "$v_option_arg" ]; then
echo "Argnument value for option -v: $v_option_arg"
fi
if [ ! -z "$r_option_arg" ]; then
echo "Argnument value for option -r: $r_option_arg"
fi
if [ ! -z "$h_option_arg" ]; then
echo "Argnument value for option -h: $h_option_arg"
fi
Run Code Online (Sandbox Code Playgroud)
这似乎工作成功。
接下来,我通过省略参数来测试脚本的稳健性:
$ bash testopts.sh -v -r 2
Argnument value for option -v: -r
Run Code Online (Sandbox Code Playgroud)
这不是我所期待的。如何让它区分一个选项和一个选项参数的差异?
我想让我的脚本更加健壮,这样如果给出一个没有参数的选项,我可以发出一条合适的错误消息。
注意:每个选项都必须有一个选项参数。
我可以用 来做到这一点getopts吗?
从man bashshell 内置命令中,getopts:
optstring 包含要识别的选项字符;如果一个字符后面跟着一个冒号,则该选项应该有一个参数,该参数应该用空格与其分隔。
从你的脚本:
while getopts ":v:r:h:" opt
Run Code Online (Sandbox Code Playgroud)
bash你明确地告诉我们-v需要争论。在 的情况下-v -r 2,-r是 的参数-v,2其余作为脚本的非选项参数。
按照设计工作,这是能力的极限getopts。
您可以做的是检查参数是否为-v数字(因为这似乎是您的脚本所期望的),并在给定的情况下通知用户确实-v 需要数字,但事实-r并非如此。但这是您的脚本在这种"v")情况下需要做的事情,而不是getopts可以处理的事情。
case $opt in
"v")
v_option_arg="$OPTARG"
if [[ ! "${v_option_arg}" =~ ^[0-9]*$ ]]
then
echo "Error: Option '-v' expects numeric argument, you gave: ${v_option_arg}"
exit 1
fi
;;
Run Code Online (Sandbox Code Playgroud)