Go Getopt —— Go 解析命令行参数工具
Go GetOpt,让你在 go 里解析命令行参数无聊地跟写 shell 脚本一样。
为了不引起混淆,以下说明将使用
go getopt
表示本代码仓库
shell getopt
、getopt 命令
表示 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 程序解析命令行参数方便一点。
- 只想解析出字符串形式参数,然后自己做处理或转换。
- 不想让类型断言、类型转换代码到处乱飞,也不需要调用的库提供
GetInt
、MustGetInt
之类的方法。 忘不了前任习惯了写 shell,想找个差不多的库接盘。- 不喜欢
flag
、pflag
这种类型的解析方式(pflag
也很久没维护了)。 - 不想用
cobra
这种很繁琐的库。
其他问题
并发(协程)安全吗?
没办法做到,也没必要。C 的 getopt
和 getopt_long
方法本身就不是并发安全的(用了全局变量 optind
、optarg
来存储中间状态)。
而且,命令行应该只需要解析一次就可以了吧。有必要多次解析吗🤔?
支持哪些平台?
这个库是用 cgo
包装 libc
中的 getopt_long
方法实现的。原理和 shell getopt 命令行程序差不多。目前主流的 libc
都是支持的:
mingw
/msvc
Windows 系glibc
Debian 系、CentOS 系musl
Alpineuclibc-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
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

低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
每日一博 | 从 generator 的角度看 Rust 异步代码
文|Ruihang Xia 目前参与边缘时序数据存储引擎项目 本文 6992 字 阅读 18 分钟 前 言 作为 2018 edition 一个比较重要的特性 Rust 的异步编程现在已经得到了广泛的使用。使用的时候难免会好奇它是如何运作的,这篇文章尝试从 generator 以及变量捕获的方面进行探索,而后介绍了在嵌入式时序存储引擎 ceresdb-helix 的研发过程中遇到的一个场景。 囿于作者水平内容难免存在一些错漏之处,还烦请留言告知。 PART. 1 async/.await, coroutine and generator async/.await 语法在 1.39 版本[1]进入 stable channel,它能够很方便地编写异步代码: 、、、java async fn asynchronous() { // snipped } async fn foo() { let x: usize = 233; asynchronous().await; println!("{}", x); 、、、 在上面的示例中,局部变量 x 能够直接在一次异步过程(fn asynchoro...
- 下一篇
W3C 成立元宇宙互操作性社区小组
W3C 社区成员近期成立了元宇宙互操作性社区小组:Open Metaverse Interoperability Group(OMI)。 小组目标 小组的目标是通过设计和促进围绕身份标识、社交图谱、库存的协议来桥接虚拟世界。除技术工作外,小组还致力于创建一个由艺术家、创建者、开发人员和其他创新者组成的社区,以探索围绕虚拟世界设计和开发的概念。当前探索的领域涵盖: 身份 好友列表/社交图谱 库存/交易虚拟项目 形象化符号(Avatars) 3D 内容 可移植脚本对象/场景 近期计划 小组支持加强元宇宙作为一个面向所有人的开放、可互操作资源,近期工作侧重于: 围绕小组目标定义关键结果 寻求一或多位小组主席来协调日常工作 界定小组工作范围 确定在推动标准/协议开发之外的职责 编写小组工作章程 探索参与激励机制 如何参与? 社区组面向公众开放,点击 “join”加入该组: https://www.w3.org/community/metaverse-interop/ 欢迎通过以下方式实时跟进小组进度: 线上交流频道: https://discord.gg/NJtT9grz5E GitHub 讨...
相关文章
文章评论
共有0条评论来说两句吧...