繁体   English   中英

BASH getopts可选参数

[英]BASH getopts optional arguments

我正在尝试创建一个shell脚本,它有两个必需参数(arg1,arg2),然后是一个可选的-b标志加上用户选择使用该标志时需要遵循的参数。

让我解释:

这是一个安装脚本,它利用GIT从Github存储库中获取应用程序。 用户键入终端f.ex。:

./shellscript.sh new <app_name> # fetches master branch by default

并且脚本从此存储库中获取主分支的实例。 但是,用户是否应该选择使用可选的-b标志,这意味着他/她想要指定要获取的分支,例如开发分支。 意味着用户可以这样做:

./shellscript.sh new <app_name> -b develop # or which ever branch there is available

我也很好奇如何使脚本工作,以便用户在'new'参数和'app_name'参数之前键入-b标志+ branch_name并不重要。 但这可能不是目前最重要的事情。

要知道我正在尝试构建什么,这里是一个指向我当前脚本的链接,它只接受两个必需参数并且只获取主分支: My Super Cool Artisan Executable Script

PS:我一直在尝试使用getopts的很多例子,我在Stackoverflow和其他博客上都找到了这些例子,但是没有一个帮助我完全使它工作。 因此,我在这里向你们所有人寻求帮助。

非常感谢,请务必查看我的Linux Mint / Ubuntu - 仅适用于酷人的安装后脚本(您和那些从Windows / Mac切换到Linux的人)

此致,Villi

我通常会自己编写以允许短期和长期期权:

function Usage()
{
cat <<-ENDOFMESSAGE

$0 [OPTION] REQ1 REQ2

options:

    -b -branch  branch to use
    -h --help   display this message

ENDOFMESSAGE
    exit 1
}

function Die()
{
    echo "$*"
    exit 1
}

function GetOpts() {
    branch=""
    argv=()
    while [ $# -gt 0 ]
    do
        opt=$1
        shift
        case ${opt} in
            -b|--branch)
                if [ $# -eq 0 -o "${1:0:1}" = "-" ]; then
                    Die "The ${opt} option requires an argument."
                fi
                branch="$1"
                shift
                ;;
            -h|--help)
                Usage;;
            *)
                if [ "${opt:0:1}" = "-" ]; then
                    Die "${opt}: unknown option."
                fi
                argv+=(${opt});;
        esac
    done 
}

GetOpts $*
echo "branch ${branch}"
echo "argv ${argv[@]}"

Unix实用程序通常在位置参数之前使用可选参数(“flags”),尽管大多数GNU实用程序(包括C库函数getopt的GNU实现)都会getopt命令行参数,以便首先使用可选参数。 但是,bash内置的getopts不会随机播放,这意味着如果你愿意,你可以这样做。

getopts始终以参数开头,参数的编号是变量OPTIND的值。 (每次执行bash函数时OPTIND都设置为1,并且它是一个全局变量。因此需要相互调用的bash函数需要注意。)如果你愿意,你可以自己设置OPTIND,然后下一个对getopts调用将从该索引开始。 或者,您可以使用shift来移动所有命令行参数。

所以,例如,你可以这样做:

# "shift" version: always shift consumed arguments
local verb="$1" branch=master app_name option
shift
case $verb in
  new)  app_name="$1"
        shift
        while getopts b: option; do
          case $option in
            b) branch=$OPTARG;;
            *) # handle the error;;
          esac
        done
        shift $((OPTIND - 1));;
  *) # handle the error or other subcommands;;
esac
# At this point, there are still arguments if ((OPTIND > 0))

要么:

# non-shift version: use OPTIND to index arguments
local verb="${!OPTIND}" branch=master app_name option
OPTIND=$((OPTIND + 1))
case $verb in
  new)  app_name="${!OPTIND}"
        OPTIND=$((OPTIND + 1))
        while getopts b: option; do
          case $option in
            b) branch=$OPTARG;;
            *) # handle the error;;
          esac
        done;;
  *) # handle the error or other subcommands;;
esac
# At this point, there are still arguments if ((OPTIND > $#))

一点点简化版本,使用该getopts可以报​​告错误:

#!/usr/bin/bash

help() { echo -e "Usage\n\t$0: new <app_name> [-b <develop>]" >&2;}
die() { [ -n "$1" ] && echo -e "Error: $1\n" >&2; help; [ -z "$1" ]; exit;}

[ $# -lt 2 ] && die "Too few args"
[ $1 != "new" ] && die "Bad first arg ($1)"
app_name=$2
shift 2

unset develop
while getopts "b:" opt; do
  case $opt in
    \?) exit 1;;
    b) develop="$OPTARG";;
  esac
done

echo "app_name: $app_name, develop: $develop"

测试:

$./test new App
app_name: App, develop:
$./test new App -b Dev
app_name: App, develop: Dev

无论如何,我可能会建议使用标准的参数传递方式。 而不是new你可以使用-n

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM