Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/search/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
带标志的Bash函数,其中任意一个是可选的?_Bash - Fatal编程技术网

带标志的Bash函数,其中任意一个是可选的?

带标志的Bash函数,其中任意一个是可选的?,bash,Bash,我试图编写一个bash函数来删除本地和远程git分支。我希望它像这样运行: $ db -r <branch_name> // deletes remote branch with name <branch_name> $ db -l <branch_name> // deletes local branch with name <branch_name> $ db -lr <branch_name> // deletes local a

我试图编写一个bash函数来删除本地和远程git分支。我希望它像这样运行:

$ db -r <branch_name> // deletes remote branch with name <branch_name>
$ db -l <branch_name> // deletes local branch with name <branch_name>
$ db -lr <branch_name> // deletes local and remote with <branch_name>
我还想抽象git分支-d和git push-origin——删除对其他函数的调用以避免重复,但在bash中很难做到这一点:/

谢谢你的帮助

更新 起初的 好的,这里有一些有效的方法:

db () {
    declare opt
    declare OPTARG
    declare OPTIND

    has_l_option=false
    has_r_option=false

    while getopts :rl opt; do
        case $opt in
            r) has_r_option=true ;;
            l) has_l_option=true ;;
            :) echo "Missing argument for option -$OPTARG"; exit 1;;
           \?) echo "Unknown option -$OPTARG"; exit 1;;
        esac
    done

    shift $(( OPTIND - 1 ))

    if $has_l_option; then
        git branch -d $1
    fi

    if $has_r_option; then
        git push origin --delete $1
    fi
}

在我看来,这几次重复几乎不值得费心将其外包到自己的功能中。到底是什么给你带来了问题?这两个选项是独立的;不要一起测试它们<代码>$has\u l\u选项和&git分支-d“$1”$has_r_option&&git push origin——删除“$1”。选项字符串“
:r:l:
”意味着
-l
-r
都接受一个选项参数——也就是说,如果同时使用这两个参数,则需要使用语法
db-r-l
(在循环中使用
$OPTARG
)。我很确定你想要的是
:rl
。@Sam,很公平。我只是觉得我应该学习如何在bash中调用helper函数。第二个不起作用,因为您没有改变选项,所以“$1”包含函数的第一个选项。我使用第1种风格:使用getopts只处理选项,然后再做真正的工作。您还应该本地化“has*option”变量。并且,根据您的偏好,您可以编写
$has\u l\u option&&git branch-d“$1”
不要忘记引用您的变量:第一个更好。在对所有标志执行操作之前,您应该始终解析和验证它们。我希望这是每个人首先想到的解决办法
# Takes -r or -l and a branch name
# and deletes the local and/or remote branch with that name
db () {
    declare opt
    declare OPTARG
    declare OPTIND

    BRANCH_NAME="$2"
    HAS_L_OPTION=false
    HAS_R_OPTION=false

    while getopts :rl opt; do
        case "$opt" in
            r) HAS_R_OPTION=true ;;
            l) HAS_L_OPTION=true ;;
            :) echo "Missing argument for option -$OPTARG"; return 1;;
           \?) echo "Unknown option -$OPTARG"; return 1;;
        esac
    done

    shift $(( OPTIND - 1 ))

    perform_branch_deletes_given "$BRANCH_NAME" "$HAS_L_OPTION" "$HAS_R_OPTION"

    echo "All done!"
}

# Helper
perform_branch_deletes_given () {
    BRANCH_NAME="$1"
    L="$2"
    R="$3"

    if "$L"; then
        git branch -D "$BRANCH_NAME"
    fi

    if "$R"; then
        git fetch -p origin  # prune local "cache" of remote branches
        echo "Local 'cache' of remote branches pruned"

        git push origin --delete "$BRANCH_NAME"
    fi
}
db () {
    declare opt
    declare OPTARG
    declare OPTIND

    has_l_option=false
    has_r_option=false

    while getopts :rl opt; do
        case $opt in
            r) has_r_option=true ;;
            l) has_l_option=true ;;
            :) echo "Missing argument for option -$OPTARG"; exit 1;;
           \?) echo "Unknown option -$OPTARG"; exit 1;;
        esac
    done

    shift $(( OPTIND - 1 ))

    if $has_l_option; then
        git branch -d $1
    fi

    if $has_r_option; then
        git push origin --delete $1
    fi
}