当前位置:网站首页>Cobra 快速入门 - 专为命令行程序而生
Cobra 快速入门 - 专为命令行程序而生
2022-07-06 10:17:00 【华为云】
最近一直在看 Istio(一个 Service Mesh
框架)相关的东西,当看到其源码时发现了一个新东西 Cobra
,一查却发现这是个好东西,用的地方可不少,比如:Docker
、Kubernetes
等都有它的身影存在。为了更好的了解这些开源框架(如,Istio
、Kubernetes
等),势必需要对 Cobra
做一个详细的了解,后续可能用到它的地方会很多。今天就 Cobra
做一个整体的介绍,让我们对它能有所认识,或许今后你的项目中也会用到它。
1、Cobra 介绍
1.1 Cobra 概述
Cobra
是一个 Golang 包,它提供了简单的接口来创建命令行程序。同时,Cobra
也是一个应用程序,用来生成应用框架,从而开发以 Cobra
为基础的应用。
1.2 主要功能
Cobra 的主要功能如下:
- 简易的子命令行模式,如
app server
,app fetch
等等。 - 完全兼容
posix
命令行模式。 - 嵌套子命令
subcommand
。 - 支持全局,局部,串联
flags
。 - 使用
cobra
很容易生成应用程序和命令(cobra init appname
和cobra add cmdname
)。 - 提供智能化的提示(如,输出
app srver
命令,将提示 你是要输入app server
吗?)。 - 自动生成
commands
和flags
的帮助信息。 - 自动生成详细的
help
信息,如app -help
。 - 自动识别帮助
flag
、-h
,--help
。 - 自动生成应用程序在
bash
下命令自动完成功能。 - 自动生成应用程序的
man
手册。 - 命令行别名。
- 自定义
help
和usage
信息。 - 可选的与
viper
的紧密集成。
对于命令行程序而言,上面这些功能简直就是量身打造。
1.3 应用举例
Cobra
被用于许多 Go 项目中,例如:Kubernetes、Hugo和Github CLI等,更多广泛使用的项目有:
(来源于:https://github.com/spf13/cobra/blob/master/projects_using_cobra.md)
- Arduino CLI
- Bleve
- CockroachDB
- Cosmos SDK
- Delve
- Docker (distribution)
- Etcd
- Gardener
- Giant Swarm’s gsctl
- Git Bump
- Github CLI
- GitHub Labeler
- Golangci-lint
- GopherJS
- Helm
- Hugo
- Istio
- Kool
- Kubernetes
- Linkerd
- Mattermost-server
- Metal Stack CLI
- Moby (former Docker)
- Nanobox/Nanopack
- OpenShift
- Ory Hydra
- Ory Kratos
- Pouch
- ProjectAtomic (enterprise)
- Prototool
- Random
- Rclone
- Skaffold
- Tendermint
- Twitch CLI
- Werf
看了这些,一个字“赞”,两个字“优秀”!
了解了 Cobra
后,再去看这些 Kubernetes
、etcd
、Registry
等开源项目的代码时,也就大概知道如何去看了,这也就是我学习 Cobra
的目的。
2、概念
Cobra 是基于命令(commands
)、参数(arguments
)、选项(flags
)而创建的。
在具体了解、使用Cobra前有一些概念需要提前知晓一下:命令(commands
)、参数(arguments
)、选项(flags
)这几个概念。
- commands:命令代表行为,一般表示 action,即运行的二进制命令服务。同时可以拥有子命令(children commands)
- arguments:参数代表命令行参数。
- flags:选项代表对命令行为的改变,即命令行选项。二进制命令的配置参数,可对应配置文件。参数可分为全局参数和子命令参数。
最好的命令行程序在实际使用时,就应该像在读一段优美的语句,能够更加直观的知道如何与用户进行交互。执行命令行程序应该遵循一般的格式: APPNAME VERB NOUN --ADJECTIVE
或 APPNAME COMMAND ARG --FLAG
。
比如下面的示例:
# server是 commands,port 是 flaghugo server --port=1313# clone 是 commands,URL 是 arguments,brae 是 flaggit clone URL --bare
再比如:
[email protected] ~ % docker info --help Usage: docker info [OPTIONS]Display system-wide informationOptions: -f, --format string Format the output using the given Go template
你没有看错,像 Docker 这种这么复杂的命令都是用 Cobra 是实现的,其必有过人之处,下一节就让我们一起来看看如何实现一套属于自己的命令行工具吧!
3、Cobra 实战
实战是最好的学习方式! 本节将从一个实战带你快速入门 Cobra。
3.1 环境准备
3.1.1 前提条件&环境
- 操作系统:MacOS
- Go 环境:go 1.16
- Go 开发 IDE:VSCode
(上述环境可以个人环境而定,不做限制)
3.1.2 Cobra 安装
使用 go get
命令获取最新版本的 Cobra 库。下面命令将会安装 Cobra 及其相关依赖包:
go get -u github.com/spf13/cobra/cobra
下载安装完 Cobra 后,打开 GOPATH 目录,在 bin 目录下会下载好 cobra 程序(Window: cobra.exe, MacOS: cobra)。
3.1.3 工程初始化(Cobra 代码生成器)
假设现需要开发一个基于 Cobra 的 CLI 的命令行程序,命名为 cobra-demo
。
由于 Cobra 提供了代码生成器的功能,我们可以直接使用 Cobra 提供的初始化命令 cobra init
进行快速初始化创建 Cobra 工程。
切换到 GOPATH
目录(如,/Users/xcbeyond/github
),执行命令 cobra init --pkg-name
,如下:
[email protected] github % .\bin\cobra init cobra-demo --pkg-name github.com/xcbeyond/cobra-demoYour Cobra application is ready at/Users/xcbeyond/github/cobra-demo
初始化成功后,cobra-demo 程序目录结构如下:
.├── cmd│ ├── root.go│ └── show.go├── go.mod├── go.sum└── main.go
3.1.4 运行
执行命令 go run
运行:
[email protected] cobra-demo % go run main.goA longer description that spans multiple lines and likely containsexamples and usage of using your application. For example:Cobra is a CLI library for Go that empowers applications.This application is a tool to generate the needed filesto quickly create a Cobra application.
3.2 实战
这里以一个简单的 time
命令为例,实战讲解如何 Cobra 开发一个命令。
功能如下:
show
:查看当前时间。parse
:指定时间格式 –format,parse 为 show 的子命令
3.2.1 实现 show 命令(Command命令)
- 添加 show 命令通过命令
cobra add
添加 show 命令:
[email protected] cobra-demo % ../bin/cobra add showshow created at /Users/xcbeyond/github/cobra-demo
- 此时,项目目录下会创建一个
show.go
文件,在该文件中可完成命令的具体操作逻辑。下面是show.go
文件的初始代码:
// showCmd represents the show commandvar showCmd = &cobra.Command{ Use: "show", Short: "A brief description of your command", Long: `A longer description that spans multiple lines and likely contains examplesand usage of using your command. For example:Cobra is a CLI library for Go that empowers applications.This application is a tool to generate the needed filesto quickly create a Cobra application.`, Run: func(cmd *cobra.Command, args []string) { fmt.Println("show called") },}func init() { rootCmd.AddCommand(showCmd) // Here you will define your flags and configuration settings. // Cobra supports Persistent Flags which will work for this command // and all subcommands, e.g.: // showCmd.PersistentFlags().String("foo", "", "A help for foo") // Cobra supports local flags which will only run when this command // is called directly, e.g.: // showCmd.Flags().BoolP("toggle", "t", false, "Help message for toggle")}
&cobra.Command
作为命令的定义,其中有如下变量:
Use
:用于指定具体的命令,如:show。Short
:命令的简短描述。Long
:命令的详细描述。Run
:命令执行入口,用于实现命令的具体处理逻辑。
rootCmd.AddCommand(showCmd)
命令的添加,将命令添加到根命令。(Cobra 支持命令的子命令)
- 实现显示当前时间逻辑
在 &cobra.Command.Run 中添加获取当前时间逻辑time.Now()
:
var showCmd = &cobra.Command{ Use: "show", Short: "A brief description of your command", Long: `A longer description that spans multiple lines and likely contains examplesand usage of using your command. For example:Cobra is a CLI library for Go that empowers applications.This application is a tool to generate the needed filesto quickly create a Cobra application.`, Run: func(cmd *cobra.Command, args []string) { // show current time fmt.Println(time.Now()) },}
- 修改 help 命令
help 命令有两个,一个是 short,一个是 lang,很明显 short 命令用来定义简短的说明,lang 命令用来定义详细说明,下面我们修改 show 命令的 help:
var showCmd = &cobra.Command{ Use: "show", Short: "Displays the current time", Long: `You can use the time show command to view the current time. For example:$ ./cobra-demo show2021-03-19 14:34:20.9320241 +0800 CST m=+0.378845301`, Run: func(cmd *cobra.Command, args []string) { // show current time fmt.Println(time.Now()) },}
- 运行
执行 show 命令:
[email protected] cobra-demo % go run main.go show2021-07-31 14:49:27.3582836 +0800 CST m=+0.176660901
执行 show –help 命令:
[email protected] cobra-demo % go run main.go show --helpYou can use the time show command to view the current time. For example:$ ./cobra-demo show2021-07-31 14:34:20.9320241 +0800 CST m=+0.378845301Usage:cobra-demo show [flags]Flags:-h, --help help for showGlobal Flags: --config string config file (default is $HOME/.cobra-demo.yaml)
4、总结
Cobra-demo 只是简单的阐述了由几部分组成,在实际项目中要比这复杂的很多,一般都是拥有多个子命令,但核心内容都是类似的。
边栏推荐
- 从交互模型中蒸馏知识!中科大&美团提出VIRT,兼具双塔模型的效率和交互模型的性能,在文本匹配上实现性能和效率的平衡!...
- STM32按键状态机2——状态简化与增加长按功能
- HMS Core 机器学习服务打造同传翻译新“声”态,AI让国际交流更顺畅
- Smart street lamp based on stm32+ Huawei cloud IOT design
- 重磅!蚂蚁开源可信隐私计算框架“隐语”,主流技术灵活组装、开发者友好分层设计...
- Grafana 9.0 正式发布!堪称最强!
- UDP协议:因性善而简单,难免碰到“城会玩”
- Interview shock 62: what are the precautions for group by?
- Recursive way
- Manifest of SAP ui5 framework json
猜你喜欢
MS-TCT:Inria&SBU提出用于动作检测的多尺度时间Transformer,效果SOTA!已开源!(CVPR2022)...
Recommend easy-to-use backstage management scaffolding, everyone open source
Getting started with pytest ----- allow generate report
Interview shock 62: what are the precautions for group by?
OliveTin能在网页上安全运行shell命令(上)
I want to say more about this communication failure
[swoole series 2.1] run the swoole first
STM32按键状态机2——状态简化与增加长按功能
RB157-ASEMI整流桥RB157
C语言指针*p++、*(p++)、*++p、*(++p)、(*p)++、++(*p)对比实例
随机推荐
Interview assault 63: how to remove duplication in MySQL?
Open source and safe "song of ice and fire"
C语言指针*p++、*(p++)、*++p、*(++p)、(*p)++、++(*p)对比实例
OpenEuler 会长久吗
MS-TCT:Inria&SBU提出用于动作检测的多尺度时间Transformer,效果SOTA!已开源!(CVPR2022)...
Declval (example of return value of guidance function)
Compilation principle - top-down analysis and recursive descent analysis construction (notes)
This article discusses the memory layout of objects in the JVM, as well as the principle and application of memory alignment and compression pointer
d绑定函数
Manifest of SAP ui5 framework json
Appium automated test scroll and drag_ and_ Drop slides according to element position
MSF横向之MSF端口转发+路由表+SOCKS5+proxychains
递归的方式
1700C - Helping the Nature
What is the reason why the video cannot be played normally after the easycvr access device turns on the audio?
Transfer data to event object in wechat applet
QT中Model-View-Delegate委托代理机制用法介绍
Interesting - questions about undefined
Compilation Principle -- C language implementation of prediction table
Distinguish between basic disk and dynamic disk RAID disk redundant array