首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >BASH getopts可选参数

BASH getopts可选参数
EN

Stack Overflow用户
提问于 2013-06-10 10:02:52
回答 3查看 10.3K关注 0票数 2

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

让我解释一下:

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

代码语言:javascript
复制
./shellscript.sh new <app_name> # fetches master branch by default

该脚本从该存储库中获取主分支的一个实例。然而,如果用户选择使用可选的-b标志,这意味着他/她想要指定要获取哪个分支,例如开发分支。这意味着用户可以这样做:

代码语言:javascript
复制
./shellscript.sh new <app_name> -b develop # or which ever branch there is available

我也很好奇你是如何让脚本工作的,这样即使用户在‘-b’参数和'app_name‘参数之前输入新的flag+branch_name也无关紧要。但这可能不是目前最重要的事情。

要知道我到底想要构建什么,这里有一个指向我当前脚本的链接,该脚本只接受两个强制参数,并且只获取主分支:My Super Cool Artisan Executable Script

附注:我已经尝试了很多使用getopts的例子,我在Stackoverflow和其他博客上都找到了getopts,但没有一个能帮助我完全做到这一点。所以我在这里向你们这些伟大的人寻求帮助。

非常感谢,请务必查看我的Linux Mint / Ubuntu - Post Install Script for only cool people(you guys and those switching over to Linux from Windows/Mac)

你好,维利

EN

回答 3

Stack Overflow用户

发布于 2013-06-10 10:39:11

我通常编写自己的代码,以允许使用短选项和长选项:

代码语言:javascript
复制
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[@]}"
票数 6
EN

Stack Overflow用户

发布于 2013-06-10 10:40:13

Unix实用程序通常在位置参数之前采用可选参数(“标志”),尽管大多数GNU实用程序,包括C库函数getopt的GNU实现,都将命令行参数打乱,以便可选参数优先出现。但是,内置在getopts中的bash不能混洗,这意味着如果您愿意,可以由您决定是否这样做。

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

因此,例如,您可以这样做:

代码语言:javascript
复制
# "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))

或者:

代码语言:javascript
复制
# 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 > $#))
票数 2
EN

Stack Overflow用户

发布于 2013-06-11 16:30:33

稍微简化一点的版本,使用getopts可以报告错误:

代码语言:javascript
复制
#!/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"

测试:

代码语言:javascript
复制
$./test new App
app_name: App, develop:
$./test new App -b Dev
app_name: App, develop: Dev

无论如何,我建议使用标准的参数传递方式。您可以使用-n代替new

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/17016007

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档