我有一个 Bash 函数,用于将 select 语句与
git checkout
一起使用。效果很好。我想阻止某个用例,但我不知道如何阻止。如何防止非 optarg 值作为 "$1"
传递给函数。例如:
$ gco hello
不应执行任何操作,因为 hello
不与 -b
标志关联。 <-- Need to implement$ gco -b hello
应该检查分支hello
。 <-- Working$ gco
应显示 select
菜单。 <-- Working正如预期的那样,检查
"$1"
并不是答案,因为它会干扰潜在的 optargs。
if [ -z "$1" ]; then
echo "$1"
return
fi
gco () {
local branch=""
while getopts :hb: opt; do
case "$opt" in
h)
echo "NAME: gco - git branch to check out."
echo "SYNOPSYS: gco [-b branch]"
echo "-h Display help text."
echo "-b branch"
return
;;
b) branch="$OPTARG" ;;
:) echo "Missing argument for option -$OPTARG"; return 1 ;;
\?) echo "Unknown option -$OPTARG"; return 1 ;;
esac
done
if [ "$branch" != "" ]; then
git checkout "$branch"
return
fi
echo "Which branch would you like to check out?"
select b in $(git branch | sed 's/* / /'); do
git checkout "$b"
return
done
}
谢谢!
使用 getopts 的典型方法是在 getopts 完成后“移动”解析的选项。所以在 while 循环之后你可以做
shift $((OPTIND - 1))
删除所有已解析的选项。
OPTIND
表示 getopts 将检查的下一个选项,因此在循环之后它指向第一个非选项。例如,使用 调用函数时
gco -b master
# OPTIND is 3 after the while loop
gco hello
# OPTIND is 1 after the while loop
现在你实际上可以检查
$1
是否它们是更多的非可选参数,或者在你的情况下它可能就足够了
[[ $# == 0 ]] || return
单独使用通用选项处理器,您无法检测参数缺少选项的情况。例如。用户想要
gco -b hello
但忘记了 -b
。这种情况 gco hello
看起来没有选项,后面跟着一个非选项参数。
如果程序有没有非选项参数,那么这就是处理错误的方式。
gco: error, unexpected "hello" argument: option expected.
如果程序具有非选项参数,但它们必须具有某些特征(例如必须是现有文件的名称),那么它会这样:
gco: no such path: "hello".
除此之外,您的程序还可以尝试临时启发式方法。它可以注意到没有找到文件,但
hello
恰好是分支的名称。
gco: no such path: "hello".
gco: there is a branch "hello". Did you mean -b "hello"?
或
gco: unexpected non-option argument: "hello"
gco: there is a branch "hello". Did you mean -b "hello"?
选项解析器通常处理选项。他们处理已知的参数,标记未知的参数,然后将非选项参数留给程序处理。