Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >Go通过cobra快速构建命令行应用

Go通过cobra快速构建命令行应用

作者头像
你大哥
发布于 2022-06-08 09:18:17
发布于 2022-06-08 09:18:17
51200
代码可运行
举报
文章被收录于专栏:容器云实践容器云实践
运行总次数:0
代码可运行

来自jetbrains Go 语言现状调查报告 显示:在go开发者中使用go开发实用小程序的比例为31%仅次于web,go得益于跨平台、无依赖的特性,用来编写命令行或系统管理这类小程序非常不错。

本文主要介绍Steve Francia(spf13)大神写的用于快速构建命令行程序的golang包cobra,基于cobra写命令行的著名项目一只手数不过来:Docker CLI、Helm、istio、etcd、Git、Github CLI ...

下面进入正题

cobra能帮我们做啥?


cobra包提供以下功能:

  • 轻松创建基于子命令的 CLI:如 app serverapp fetch等。
  • 自动添加 -h, --help等帮助性Flag
  • 自动生成命令和Flag的帮助信息
  • 创建完全符合 POSIX 的Flag(标志)(包括长、短版本)
  • 支持嵌套子命令
  • 支持全局、本地和级联Flag
  • 智能建议( app srver... did you mean app server?)
  • 为应用程序自动生成 shell 自动完成功能(bash、zsh、fish、powershell)
  • 为应用程序自动生成man page
  • 命令别名,可以在不破坏原有名称的情况下进行更改
  • 支持灵活自定义help、usege等。
  • 无缝集成viper构建12-factor应用

cobra遵循 commands, arguments & flags结构。

举例来说

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#appname command  arguments
docker pull alpine:latest
#appname command flag
docker ps -a
#appname command flag argument
git commit -m "msg"

开发者可根据情况进行自组织。

cobra基础使用


安装cobra包和二进制工具cobra-cli,cobra-cli可以帮助我们快速创建出一个cobra基础代码结构。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
go get -u github.com/spf13/cobra@latest
go install github.com/spf13/cobra-cli@latest

启用 GO111MODULE=on,我们初始化一个xpower

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
# go mod init  xpower
go: creating new go.mod: module xpower

使用cobra-cli初始化基础代码结构

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
# cobra-cli  init
Your Cobra application is ready at /root/demo/xpower

#查看目录结构
# tree xpower
xpower
├── cmd
│   └── root.go
├── go.mod
├── go.sum
├── LICENSE
└── main.go

1 directory, 5 files

运行demo可以看到cobra包本身的一些提示信息。

查看 main.go,cobra-cli为我们创建了一个cmd的包并且调用了包里面的 Execute()函数

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
/*
Copyright © 2022 NAME HERE <EMAIL ADDRESS>

*/
package main

import "xpower/cmd"

func main() {
        cmd.Execute()
}

从上面的目录结构中可以看到cmd包目前只有一个 root.go,我们可以在这里操作根命令相关的内容。

大多数时候CLI可能会包含多个子命令比如 git clonegit add,cobra-cli可通过add 添加子命令。

现在我们添加wget和ping子命令,即接下来我们将通过xpower来重写wget和ping的部分功能。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
cobra-cli add wget
cobra-cli add ping

现在的目录结构如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
# tree xpower
xpower
├── cmd
│   ├── ping.go
│   ├── root.go
│   └── wget.go
├── go.mod
├── go.sum
├── LICENSE
└── main.go

pingwget已经被集成到root.go中

wget.go

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
package cmd

import (
    "fmt"

    "github.com/spf13/cobra"
)

// wgetCmd represents the wget command
var wgetCmd = &cobra.Command{
    Use:     "wget",
    Example: "xpower wget iqsing.github.io/download.tar -o /tmp",
    Short:   "wget is a download cli.",
    Long:    `use wget to download everything you want from net.`,
    Run: func(cmd *cobra.Command, args []string) {
        fmt.Println("wget called")  
    },
}

func init() {
    rootCmd.AddCommand(wgetCmd)

    // Here you will define your flags and configuration settings.
}

在wget.go 中定义了一个wgetCmd结构体指针,可通过查看Command结构体原型添加或移除成员变量。这里我们添加了一个 Example用于指示示例,Short和Long为命令简介,Run为wget命令的真正实现。

我们知道在go中包的init()函数会在import时执行,通过 AddCommand(wgetCmd)将wegetCmd添加到结构体 Command 成员变量commands中,包括后面我们编写的Flag也是如此。

接下来我们在结构体中添加Args用于验证(限制)参数数量,在init()函数中添加Flag -o用于保存下载的文件地址,并通过 MarkFlagRequired约束flag的参数必须输入,最后在Run中调用Download即可。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
package cmd

import (
    "fmt"
    "io"
    "log"
    "net/http"
    "os"

    "github.com/spf13/cobra"
)

var (
    output string
)

// wgetCmd represents the wget command
var wgetCmd = &cobra.Command{
    Use:     "wget",
    Example: "xpower wget iqsing.github.io/download.tar.gz -o /tmp/download.tar.gz",
    Args:    cobra.ExactArgs(1),
    Short:   "wget is a download cli.",
    Long:    `use wget to download everything you want from net.`,
    Run: func(cmd *cobra.Command, args []string) {
        fmt.Println("---wget running---")
        Download(args[0], output)
    },
}

func init() {
    rootCmd.AddCommand(wgetCmd)
    // Here you will define your flags and configuration settings.

    wgetCmd.Flags().StringVarP(&output, "output", "o", "", "output file")
    wgetCmd.MarkFlagRequired("output")
}
func Download(url string, path string) {
    out, err := os.Create(path)
    check(err)
    defer out.Close()

    res, err := http.Get(url)
    check(err)
    defer res.Body.Close()

    _, err = io.Copy(out, res.Body)
    check(err)
    fmt.Println("save as" + path)
}
func check(err error) {
    if err != nil {
        log.Fatal(err)
    }
}
args
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
Args:    cobra.ExactArgs(1)

cobra内置的参数验证也是比较多,NoArgs、OnlyValidArgs、MinimumNArgs、MaximumNArgs等等可翻阅源码args.go,可以满足基本使用,如果有自己的特殊要求可以通过解析arg来实现。

flags
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
wgetCmd.Flags().StringVarP(&output, "output", "o", "", "output file(required)")

flag包含局部和全局两种,全局flag在父命令定义后子命令也会生效,而局部flag则在哪定义就在哪生效。

如上面的局部flag,我们在wgetCmd中定义的flag只有wget这个子命令能用。

全局flag

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
rootCmd.PersistentFlags().BoolVarP(&Verbose, "verbose", "v", false, "verbose output")

StringVarpBoolVarP 用于flag数据类型限制。

简单的应用从命令行直接写入参数是很常见的,但是如果比较复杂的命令行应用参数需要非常多,再这样操作不太合理,cobra作者还写了另一个在go中很流行的包viper用于解析配置文件,比如kubectl 的yml,以及各种json

前面也说过可以无缝衔接,只需Bind一下即可。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
var author string

func init() {
  rootCmd.PersistentFlags().StringVar(&author, "author", "YOUR NAME", "Author name for copyright attribution")
  viper.BindPFlag("author", rootCmd.PersistentFlags().Lookup("author"))
}

flag还可以做依赖,比如下面username和password必须同时接收到参数。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
rootCmd.Flags().StringVarP(&u, "username", "u", "", "Username (required if password is set)")
rootCmd.Flags().StringVarP(&pw, "password", "p", "", "Password (required if username is set)")
rootCmd.MarkFlagsRequiredTogether("username", "password")

添加子命令可参考包go-ping/ping,这里不再赘述。

我们来看编译后使用如何?

通过 -h查看帮助:

参数个数错误:

需要flag -o

正确使用:

xpower 子命令ping:

xpower 子命令wget:


以上我们通过go中cobra包实现xpower命令,包含重写了简单功能的ping和wget两子命令,甚至我们还可以以此来实现自己的跨平台、无依赖的工具集。本文涉及代码已提交至仓库code/xpower

cobra包含很多开箱即用的功能,经过大量项目验证和完善,已满足大部分命令行应用构建需求。本文只介绍了一部分内容,更多内容可查看仓库spf13/cobra

通过博客阅读:iqsing.github.io

参考:

[1]

Go 语言现状调查报告: https://blog.jetbrains.com/zh-hans/go/2021/02/19/the-state-of-go/

[2]

cobra: https://github.com/spf13/cobra

[3]

viper: http://github.com/spf13/viper

[4]

args.go: https://github.com/spf13/cobra/blob/master/args.go

[5]

go-ping/ping: https://github.com/go-ping/ping

[6]

code/xpower: https://github.com/iqsing/code/tree/main/xpower

[7]

spf13/cobra: https://github.com/spf13/cobra

[8]

iqsing.github.io: https://iqsing.github.io

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2022-04-19,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 容器云实践 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
Go: 常用工具库cobra的简介与实践
来自jetbrains Go 语言现状调查报告 显示:在go开发者中使用go开发实用小程序的比例为31%仅次于web,go得益于跨平台、无依赖的特性,用来编写命令行或系统管理这类小程序非常不错。
Freedom123
2024/03/29
6310
Go: 常用工具库cobra的简介与实践
要命!我篡改了系统命令惊现事故,竟要扣我年终奖-Golang-cobra
Kubernetes、Hugo、etcd 这些知名项目都用cobra来做命令行程序。学起来!
机智的程序员小熊
2023/03/02
3140
要命!我篡改了系统命令惊现事故,竟要扣我年终奖-Golang-cobra
Go每日一库之5:cobra
cobra是一个命令行程序库,可以用来编写命令行程序。同时,它也提供了一个脚手架,
luckpunk
2023/09/13
4460
go cobra CLI工具库的简单入门
下载:go install github.com/spf13/cobra-cli@latest
用户8478947
2023/01/26
1.1K0
使用Go构建一个Data Thrashing CLI工具
以下所撰就是这个快速上手的项目。最后,我将在容器中搭建服务,并将其放入Kubernetes(k8s)集群中,不过下面操作都是在CLI环境下进行的。
大数据弄潮儿
2018/05/30
9260
Cobra 库上手—自建命令行工具
Cobra 是一个流行的 Go 语言库,用于创建强大且灵活的命令行应用程序。它由 spf13 开发,设计用于与 Go 生态系统中的其他流行库(如 Viper 配置库)无缝集成。Cobra 支持多级命令结构,允许定义根命令和任意数量的子命令,还可以轻松处理全局和本地标志。它自动生成帮助和使用信息,并支持 Bash、Zsh、Fish 和 PowerShell 的命令补全。此外,Cobra 能够生成 Markdown 格式的文档,使文档维护更加便捷。通过与 Viper 集成,Cobra 能处理配置文件和环境变量,为开发者提供了强大的工具集,使创建复杂的 Client 工具变得简单高效。Cobra 广泛应用于各种 Go 项目中,提升了 Client 应用的开发体验和维护效率。
FunTester
2025/01/23
1600
Cobra 库上手—自建命令行工具
Go之现代命令行框架Cobra
老实说,今天是我第一次见到现代命令行框架这个名词,在此之前,我并不知道这个东西的作用是什么。下面一起来了解一下这个东西。
f1sh
2024/07/27
2680
命令行工具开发 cobra 示例
Cobra 是 Go 语言中一个流行的库,用于创建命令行应用程序。它提供了一个易于使用的框架,帮助开发者快速构建强大且灵活的 CLI(Command-Line Interface)工具。Cobra 的主要特点包括命令层次结构、命令行标志(flags)和参数处理、自动生成帮助文档等。
孟斯特
2024/08/10
1770
命令行工具开发 cobra 示例
go命令行库-cobra
Cobra 是一个用于创建强大的现代 CLI 应用程序的库。几乎包含了你所需要的所有元素。
zy010101
2022/10/31
9450
[Java]快速构建一个CLI小工具
在现实开发的过程中,大家会发现很多开源的框架都会有着自己的一个CLI工具库来帮助开发者们通过命令行的方式快速的达到某些目的,比如常见的docker 命令。那么在这篇文章当中,主要给大家介绍一个golang的小框架,我们可以借助这个框架来快速搭建一个小的CLI工具。
宇宙无敌暴龙战士之心悦大王
2023/03/29
1.4K0
怎样上手cobra
cobra是go语言中一个非常强大的命令行构建工具,我们非常熟悉的docker、k8s、etcd都是基于cobra开发的。如果你想打造自己的命令行工具,那么cobra就是你的最佳选择。
闻说社
2024/06/11
1250
怎样上手cobra
cobra-强大的CLI应用程序库
Cobra是一个用于创建强大的现代CLI应用程序的库,也是一个用于生成应用程序和命令文件的程序。
happlyfox
2021/02/24
7630
cobra-强大的CLI应用程序库
Cobra 使用简要(万字带你轻松上手 Cobra 使用)
欢迎阅读本文,本文将介绍如何使用 Go 语言中的 Cobra 库快速实现一个强大的命令行客户端。命令行客户端在软件开发中扮演着重要的角色,它们提供了一种简单而直接的方式来与应用程序进行交互,使用户能够轻松地执行各种操作。而 Cobra 则是一款流行的开源库,专门用于简化命令行应用程序的开发。
繁依Fanyi
2024/03/30
4.4K0
Cobra 使用简要(万字带你轻松上手 Cobra 使用)
golang 反射1: 使用反射绑定 cobra flag 参数
cobra https://github.com/spf13/cobra 是 golang 中一个非常好用的 命令 开发库。
老麦
2022/12/24
3990
golang 反射1: 使用反射绑定 cobra flag 参数
Go系列:cobra命令
通过调用rootCmd的所有命令的SetNormalizeFunc,使得所有root命令和所有子命令都同时支持中划线参数和下划线参数
用户9805946
2024/11/25
1100
Kubernetes 学习(九)Kubernetes 源码阅读之正式篇------核心组件之 Scheduler
0. 前言 继续上一篇博客阅读 Kubernetes 源码,参照《k8s 源码阅读》首先学习 Kubernetes 的一些核心组件,首先是 kube-scheduler 本文严重参考原文:《k8s 源码阅读》之 2.2 章节:scheduler,加入部分自己阅读的体会作为自己的阅读笔记 感谢《k8s 源码阅读》的作者们辛苦编写教材,在此郑重表示感谢,望大家多多支持!~ 1. 整体设计 1.1 概述 官网描述: The Kubernetes scheduler runs as a process alo
西凉风雷
2022/11/23
3540
Kubernetes 学习(九)Kubernetes 源码阅读之正式篇------核心组件之 Scheduler
每天20分钟之cobra的例子
main.gopackage mainimport ("log""gcobra/cmd")func main() {err := cmd.Execute()if err != nil {log.Fatalf("cmd.Execute err: %v", err)}}root.gopackage cmdimport ("github.com/spf13/cobra")var rootCmd = &cobra.Command{Use: "",Short: "",Long: "",}func Execute
李子健
2022/07/10
2480
[Go]GO语言实战-GO-FLY在线客服cobra库命令行参数解析
最开始的解析命令行参数是使用的标准库里面的flag包,后来想增加新的参数的时候比较复杂和困难,因此使用cobra更加简单一些
唯一Chat
2020/09/10
7540
[Go]GO语言实战-GO-FLY在线客服cobra库命令行参数解析
智能在线客服系统源码GOFLY开发日志- 2. 开发命令行应用
我一直以来都是做PHP开发,除非是使用swoole框架,大部分PHP应用都是把代码传到服务器对应的目录里,启动nginx+php-fpm来运行PHP代码。
唯一Chat
2022/02/22
3250
使用 Cobra 创建 CLI 应用
虽然现在我们使用的大多数软件都是可视化的,很容易上手,但是这并不代表 CLI(命令行)应用就没有用武之地了,特别是对于开发人员来说,还是会经常和 CLI 应用打交道。而 Golang 就非常适合用来构建 CLI 应用,下面我们就将来介绍如何在 Golang 中构建一个 CLI 应用。
我是阳明
2020/06/15
1.5K0
推荐阅读
相关推荐
Go: 常用工具库cobra的简介与实践
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验