如何防止非 optarg 参数传入 bash 函数?

问题描述 投票:0回答:2

我有一个 Bash 函数,用于将 select 语句与

git checkout
一起使用。效果很好。我想阻止某个用例,但我不知道如何阻止。如何防止非 optarg 值作为
"$1"
传递给函数。例如:

  1. $ gco hello
    不应执行任何操作,因为
    hello
    不与
    -b
    标志关联。 <-- Need to implement
  2. $ gco -b hello
    应该检查分支
    hello
    。 <-- Working
  3. $ 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
}

谢谢!

bash getopts
2个回答
0
投票

使用 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

0
投票

单独使用通用选项处理器,您无法检测参数缺少选项的情况。例如。用户想要

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"?

选项解析器通常处理选项。他们处理已知的参数,标记未知的参数,然后将非选项参数留给程序处理。

© www.soinside.com 2019 - 2024. All rights reserved.