Bash:帮助完善自定义功能

Bash:帮助完善自定义功能

我正在学习 Bash,并且编写了一个基本函数:

wsgc () {
    # Wipe the global variable value for `getopts`.
    OPTIND=1;
    echo "git add -A";
    while getopts m:p option;
    do
        case "${option}"
        in
            m)
                COMMIT_MESSAGE=$OPTARG
                if [ "$COMMIT_MESSAGE" ]; then
                    echo "git commit -m \"$COMMIT_MESSAGE.\""
                else
                    echo "A commit message is required."
                    exit
                fi
                ;;
            p)
                echo "git push"
                exit
                ;;
            \?)
                echo "Invalid parameter."
                exit
                ;;
        esac
    done
}

然而,我正在努力解决一些问题:

  1. in不起作用,因为如果我省略了参数, ifBashm)就会介入并将我踢出会话;

    git add -A
    -bash: option requires an argument -- m
    Invalid parameter.
    logout
    Saving session...
    ...copying shared history...
    ...saving history...truncating history files...
    ...completed.
    

    [流程完成]

  2. 运行后:wsgc -m "Yo!" -p,我被踢出了会话。

    git add -A
    git commit -m "Yo."
    git push
    logout
    Saving session...
    ...copying shared history...
    ...saving history...truncating history files...
    ...completed.
    

    [流程完成]

任何建议将不胜感激。

答案1

m) 中的 if 不起作用,因为如果我省略了参数,Bash 就会介入并将我踢出会话;

您指定getopts m:p option.之后:m意思是你需要一个论证。如果您不提供它,则会出现错误。

运行后:wsgc -m“哟!” -p,我被踢出了会话。

您被踢出会话是什么意思? shell 消失了吗? 那么那是因为您获取了脚本,而不是执行了它。

话虽这么说,我强烈建议使用getopt而不是getopts.

答案2

  • 如果该-m选项未获取值,则您exit将退出 shell。
  • 如果您使用该-p选项,您exit将从 shell 中进行操作。
  • 如果您使用无效选项,您exit将退出 shell。

在所有这些情况下,您应该return而不是exit,并且在除第二种情况之外的所有情况下,您应该return 1(发出错误信号)。此外,错误消息应该使用 .redirect 重定向到标准错误流>&2

这是函数的一个版本,经过一些修改,除非命令行解析顺利,否则它不会输出任何内容。

wsgc () {
    local OPTIND=1
    local out=( "git add -A" )

    while getopts 'm:p' opt; do
        case "$opt" in
            m)  out+=( "git commit -m '$OPTARG'" ) ;;
            p)  out+=( 'git push' ) ;;
            *)  return 1 ;;
        esac
    done

    printf '%s\n' "${out[@]}"
}

如果您需要对输出进行排序(如果使用上述函数在命令行上最后一个git push输出,则只会是最后输出的内容),然后使用标志。-p这也将不是如果多次使用一个选项,则输出多个命令。

wsgc () {
    local OPTIND=1

    local message
    local do_push=0

    while getopts 'm:p' opt; do
        case "$opt" in
            m)  message="$OPTARG" ;;
            p)  do_push=1 ;;
            *)  return 1 ;;
        esac
    done

    local out=( "git add -A" )

    if [[ -n "$message" ]]; then
        out+=( "git commit -m '$message'" )
    fi

    if (( do_push )); then
        out+=( 'git push' )
    fi

    printf '%s\n' "${out[@]}"
}

该函数的最后一点可以缩短为

local out=( "git add -A" )

[[ -n "$message" ]] && out+=( "git commit -m '$message'" )
(( do_push ))       && out+=( 'git push' )

printf '%s\n' "${out[@]}"

相关内容