带标志的Bash函数,其中任意一个是可选的?
我试图编写一个bash函数来删除本地和远程git分支。我希望它像这样运行:带标志的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
$ 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
}