Go Getopt

Go 解析命令行参数工具
授权协议 Mulan
开发语言 Google Go
所属分类 开发工具、 语法解析工具
软件类型 开源软件
地区 国产
投 递 者 何玉韵
操作系统 跨平台
开源组织
适用人群 未知
 软件概览

Go GetOpt,让你在 go 里解析命令行参数 无聊地 跟写 shell 脚本一样。


为了不引起混淆,以下说明将使用

go getopt 表示本代码仓库

shell getoptgetopt 命令 表示 util-linux 中的 getopt 二进制程序

getopt(或 C getopt)表示 libc 中的 getopt 方法

但在某个上下文(如标题说明了该段是 shell getopt)中可能有时会直接使用 getopt 指代。请各位注意区分。


怎么用

go get gitee.com/go-getopt/go-getopt
package main

import (
    "fmt"
    "os"

    // 这里为了方便,直接使用 . 进行 import。
    // 这样可以直接调用 GetOpt、Get 和 Shift 方法。
    . "gitee.com/go-getopt/go-getopt"
)

func main() {
    // 传入 os.Args、options 和 longOptions 字符串参数即可
    err := GetOpt(os.Args, "ab:c::", "a-long,b-long:,c-long::")
    if err != nil {
        fmt.Fprintln(os.Stderr, err)
        os.Exit(1)
    }

    // 解析后的参数列表存储在全局变量 Args 中
    fmt.Println("Arguments:", Args)
    fmt.Println("Program name:", Args[0])

    // 接下来的步骤就和 shell 差不多了
    for loop := true; loop; {
        switch Get(1) {
        case "-a", "--a-long":
            fmt.Println("Option a")
            Shift(1)
        case "-b", "--b-long":
            fmt.Println("Option b, argument '" + Get(2) + "'")
            Shift(2)
        case "-c", "--c-long":
            if Get(2) == "" {
                fmt.Println("Option c, no argument")
            } else {
                fmt.Println("Option c with arg '" + Get(2) + "'")
            }
            Shift(2)
        case "--":
            Shift(1)
            loop = false
        default:
            fmt.Fprintln(os.Stderr, "Error: wrong argument '"+arg1+"'")
            os.Exit(1)
        }
    }
    fmt.Println("Remains:", Args[1:])
}

对比一下 shell getopt 解析命令行的脚本:

# 检查 getopt 命令是否正常运行
getopt --test > /dev/null

[ $? -ne 4 ] &&
    echo "Error: command 'getopt --test' failed in this environment." &&
    exit 1

# 设定 options 和 longOptions,调用 getopt 命令
options=ab:c::
longOptions=a-long,b-long:,c-long::

parsed=$(getopt --options=$options --longoptions=$longOptions --name "$0" -- "$@")

[ $? -ne 0 ] &&
    echo "Error: failed to parse cmd arguments" &&
    exit 1

eval "set -- $parsed"

# 循环判断是哪个 flag,处理完后 shift 掉
while true; do
    case "$1" in
        -a|--a-long)
            echo 'Option a'
            shift
        ;;
        -b|--b-long)
            echo "Option b, argument '$2'"
            shift 2
        ;;
        -c|--c-long)
            [ -n "$2" ] && \\
            echo "Option c, argument '$2'" || \\
            echo 'Option c, no argument'
            shift 2
        --)
            shift
            break
        *)
            echo "Error: wrong argument '$1'"
            exit 1
            ;;
    esac
done
echo "Remains: $@"

Go GetOpt 适合哪些人用

如果你符合以下的一条或多条,可能这个库会适合你:

  • 想用一个库让 go 程序解析命令行参数方便一点。
  • 只想解析出字符串形式参数,然后自己做处理或转换。
  • 不想让类型断言、类型转换代码到处乱飞,也不需要调用的库提供 GetIntMustGetInt 之类的方法。
  • 忘不了前任 习惯了写 shell,想找个差不多的库 接盘
  • 不喜欢 flagpflag 这种类型的解析方式(pflag 也很久没维护了)。
  • 不想用 cobra 这种很繁琐的库。

其他问题

并发(协程)安全吗?

没办法做到,也没必要。C 的 getoptgetopt_long 方法本身就不是并发安全的(用了全局变量 optindoptarg 来存储中间状态)。

而且,命令行应该只需要解析一次就可以了吧。有必要多次解析吗��?

支持哪些平台?

这个库是用 cgo 包装 libc 中的 getopt_long 方法实现的。原理和 shell getopt 命令行程序差不多。目前主流的 libc 都是支持的:

  • mingw / msvc Windows 系
  • glibc Debian 系、CentOS 系
  • musl Alpine
  • uclibc-ng BusyBox

附:各 libc getopt 和 getopt_long 源码地址

musl

https://git.musl-libc.org/cgit/musl/tree/src/misc/getopt.c

https://git.musl-libc.org/cgit/musl/tree/src/misc/getopt_long.c

glibc

https://sourceware.org/git/?p=glibc.git;a=blob;f=posix/getopt.c;h=e9661c79faa8920253bc37747b193d1bdcb288ef;hb=HEAD

https://sourceware.org/git/?p=glibc.git;a=blob;f=posix/getopt1.c;h=990eee1b64fe1ee03e8b22771d2e88d5bba3ac68;hb=HEAD

uclibc-ng

https://gogs.waldemar-brodkorb.de/oss/uclibc-ng/src/master/libc/unistd/getopt.c

https://gogs.waldemar-brodkorb.de/oss/uclibc-ng/src/master/libc/unistd/getopt_long-simple.c

  • 1. golang 命令行参数解析 golang 的命令行参数解析, 推荐两种。一个是 os.Args, 另一个是使用 flag 模块。 1.1. os.Args package main import ( "fmt" "os" ) func main() { args := os.Args // 使用 go run xx.go 1 2 3 xx aaa bbb ccc ddd

  • C语言中的getopt()函数为命令参数的获取提供了很大便利,与golang中的flag功能类似。 C语言getopt 下面以ssh中获取主机名/ip和用户名为例来示例如何使用getopt(). int get_user_host(int ac, char **av, char *host, char *user){ char *p, *cp; extern

  • 这个问题是关于php中的getopt函数.我需要将两个参数传递给php脚本,如 php script.php -f filename -t filetype 现在根据文件类型可以是u,c或s我需要做正确的操作. 我正在使用相同的开关盒: 这是我正在使用的代码: // Get filename of input file when executing through command line. $f

  • 参考: http://www.gnu.org/software/libc/manual/html_node/Example-of-Getopt.html http://en.wikipedia.org/wiki/Getopt http://www.lemoda.net/c/getopt/ http://www.ibm.com/developerworks/aix/library/au-unix-g

  • Introducing Positional arguments An example: import argparse parser = argparse.ArgumentParser() parser.add_argument("echo") args = parser.parse_args() print args.echo And running the code: $ python pr

  • Go语言中使用 protobuf 2016年05月03日 protobuf以前只支持C++, Python和Java等语言, Go语言出来后, 作为亲儿子, 那有不支持的道理呢? github地址: go protobuf. 1. 安装protobuf <1> 去这儿下载protobuf git clone  https://github.com/google/protobuf.git 运行aut

  • 问题 I am new to coding and and trying to learn as I go. I'm trying to create a python script that will grab and print all HEADERS from a list of urls in a txt file. It seems to be getting there but im

  • Getopt and getopts http://aplawrence.com/Unix/getopts.html Both "getopt" and getopts are tools to use for processing and validating shell script arguments. They are similar, but not identical. More co

  • 转自: http://cn.programmingnote.com/blog/?p=43   用过gcc的都知道gcc有许多参数。例如要将hello.c译成hello.exe并加上调试信息,用gcc hello.c -g -o hello.exe即可。现在分析gcc的参数。对于这个例子,参数可分成三个部分:输入文件(hello.c)、是否包含调试信息(-g)、输出文件 (-o hello.exe)

  • package main import ( "context" "fmt" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/client-go/kubernetes" "k8s.io/client-go/tools/clientcmd" //"k8s.io/apimachinery/pkg/apis/meta/v1/uns

 相关资料
  • 在写命令行程序(工具、server)时,对命令参数进行解析是常见的需求。各种语言一般都会提供解析命令行参数的方法或库,以方便程序员使用。如果命令行参数纯粹自己写代码解析,对于比较复杂的,还是挺费劲的。在 go 标准库中提供了一个包:flag,方便进行命令行解析。 注:区分几个概念 命令行参数(或参数):是指运行程序提供的参数 已定义命令行参数:是指程序中通过flag.Xxx等这种形式定义了的参数

  • 问题内容: 如果我想解析该怎么办: 我想要的结果是: 我更喜欢使用Apache Commons CLI ,但是文档对我上面提到的情况有些不清楚。具体来说,文档没有告诉您如何处理我在下面指定的第3种类型的选项: 我希望Apache Commons CLI可以正常工作,但是如果这些args没有选项前缀,仍然可以将常规args传递给程序。也许可以,但是文档没有这么说,因此在我阅读它时… 问题答案: 您可

  • 建立一个解析器 import argparse parser = argparse.ArgumentParser( description='This is a PyMOTW sample program', ) 简单示例 # argparse_short.py import argparse parser = argparse.ArgumentParser(description='

  • 问题内容: 在Java中解析命令行参数的好方法是什么? 问题答案: 例如,这是你用来解析2个字符串参数的方法: 从命令行使用:

  • 主要内容:flag 包概述,flag 参数类型,flag 包基本使用在编写命令行程序(工具、server)时,我们有时需要对命令参数进行解析,各种编程语言一般都会提供解析命令行参数的方法或库,以方便程序员使用。在Go语言中的 flag 包中,提供了命令行参数解析的功能。 下面我们就来看一下 flag 包可以做什么,它具有什么样的能力。 这里介绍几个概念: 命令行参数(或参数):是指运行程序时提供的参数; 已定义命令行参数:是指程序中通过 flag.Type 这种形

  • 本文向大家介绍Python命令行参数解析工具 docopt 安装和应用过程详解,包括了Python命令行参数解析工具 docopt 安装和应用过程详解的使用技巧和注意事项,需要的朋友参考一下 什么是 docopt? 1、docopt 是一种 Python 编写的命令行执行脚本的交互语言。 它是一种语言! 它是一种语言! 它是一种语言! 2、使用这种语言可以在自己的脚本中,添加一些规则限制。这样脚本

  • 本文向大家介绍python 如何利用argparse解析命令行参数,包括了python 如何利用argparse解析命令行参数的使用技巧和注意事项,需要的朋友参考一下 命令行参数工具是我们非常常用的工具,比如当我们做实验希望调节参数的时候,如果参数都是通过硬编码写在代码当中的话,我们每次修改参数都需要修改对应的代码和逻辑显然这不太方便。比较好的办法就是把必要的参数设置成通过命令行传入的形式,这样我

  • 为了方便起见,我们支持在运行 Blade 应用的时候修改一些配置,比如我在运行时指定端口: java -jar blade-app.jar --server.port=9088 当然还支持一些其他的命令行参数,看看下面的表格: 命令行参数 描述 示例 server.address 服务地址,默认是本机 0.0.0.0 回环地址 --server.address=192.168.1.100 serv