我想使用 getopts 来解析 bash 函数的参数。
while getopts ${shortopts} arg; do
但在设置变量值时遇到问题。调用myfunc -v8
或myfunc -v 8
设置vb
为 的预期值8
。
myfunc -v 8
vb, arg: ; OPTARG: 8
vb: 8
但再次运行命令myfunc -v 21
给出
myfunc -v 21
vb: 1
这是我处理选项的方法
myfunc
{
local vb=1
local arg
local shortopts="Vuhv:"
while getopts ${shortopts} arg; do
case ${arg} in
# ........................................................
("V")
printf "%s\n" "V01 Jul 2021 Wk27"
return
;;
("u")
printf "%s\n" "-V, -u, -h"
return
;;
("h")
printf "%s\n" "Prints status returned by getopt."
printf "%s\n" "-V Displays version"
printf "%s\n" "-u Displays usage"
printf "%s\n" "-h Displays help."
printf "%s\n" "-v, -vNUM Sets verbosity level."
printf "%s\n" "Example: getopt-status --"
return
;;
("v")
vb="$OPTARG"
printf '%s\n' "vb, arg: $arg ; OPTARG: $OPTARG"
;;
:)
echo "Current argument value, OPTARG: -$OPTARG" >&2
echo "Must supply an argument to -$OPTARG" >&2
;;
?)
printf "%s\n" "Invalid option, OPTARG: $OPTARG"
;;
esac
done
echo "vb: $vb"
}
答案1
正如 ilkkachu 和其他人提到的,那里存在一些错误。return
并将local
在函数内工作,因为return
将返回函数的退出代码。
这是一个可以给您一个想法的最小示例:
#!/usr/bin/env bash
die(){ echo >&2 "$@"; exit 1; }
usage(){ echo >&2 "usage: $0 [-u] [-v num] "; exit 0; }
shortopts=":Vuhv:"
while getopts "$shortopts" opt; do
case $opt in
u) usage ;;
v) case $OPTARG in
''|*[!-0-9]*) die "invalid number $OPTARG" ;;
*) val=$OPTARG ;;
esac
;;
:) die "argument needed to -$OPTARG" ;;
*) die "invalid switch -$OPTARG" ;;
esac
done
shift $((OPTIND - 1))
echo value="$val"
一些注意事项:
如果选项字符串的第一个字符是 :(冒号),这通常是无意义的,因为它前面没有选项字母,getopts 会切换到“静默错误报告模式”。在高效的脚本中,这通常是您想要的,因为它允许您自己处理错误,而不会被烦人的消息打扰。
答案2
getopts
在函数中使用时,您必须本地化OPTARG
,尤其是OPTIND
.
你可以做
myfunc() {
local OPTIND OPTARG
...
并将getopts
负责初始化它们。