概述

cobra 库是 golang 的一个开源第三方库,能够快速便捷的建立命令行应用程序。

优势:cobra 可以快速建立CLI程序,使我们更专注于命令需要处理的具体的业务逻辑。

举两个例子:

hugo server --port=1313
git clone URL --bare

都是命令行程序。

基本概念

cobra由三部分构成:commandsargumentsflags

commands:表示要执行的动作。每一个 command 表示应用程序的一个动作。每个命令可以包含子命令。

arguments:给动作传入的参数。

flags:表示动作的行为。可以设置执行动作的行为。flags 包括两种:对某个命令生效和对所有命令生效。

安装方法

go get -u github.com/spf13/cobra/cobra

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

使用方法

1.创建cobra命令行应用程序

cobra init code.byted.org/dfic/demo

$GOPATH/src/code.byted.org.dfic/ 目录下创建一个名为 democobra 命令行应用程序

main.go 文件,完成初始化 cobra 功能。

第一次初始化可能会出现这个问题 Error: required flag(s) "pkg-name" not set 解决办法

package main

import "code.byted.org/dfic/demo/cmd"

func main() {
cmd.Execute()
}

2.添加命令

2.1.基本用法

cobra add version

cmd 文件夹下生成一个新的文件 version.go,定义这个新的命令的动作。

文件内容如下:

import (
"fmt" "github.com/spf13/cobra"
) // versionCmd represents the version command
var versionCmd = &cobra.Command{
Use: "version",
Short: "A brief description of your command",
Long: `A longer description that spans multiple lines and likely contains examples
and 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 files
to quickly create a Cobra application.`,
Run: func(cmd *cobra.Command, args []string) {
fmt.Println("version called")
},
} func init() {
rootCmd.AddCommand(versionCmd) // Here you will define your flags and configuration settings. // Cobra supports Persistent Flags which will work for this command
// and all subcommands, e.g.:
// versionCmd.PersistentFlags().String("foo", "", "A help for foo") // Cobra supports local flags which will only run when this command
// is called directly, e.g.:
// versionCmd.Flags().BoolP("toggle", "t", false, "Help message for toggle")
}

编译运行

> go build -o demo

> ./demo -h

Usage:
demo [command] Available Commands:
help Help about any command
version A brief description of your command Flags:
--config string config file (default is $HOME/.demo.yaml)
-h, --help help for demo
-t, --toggle Help message for toggle 执行新添加的命令
> ./demo version
输出:version called

2.2.修改命令行为

将命令的行为添加到命令结构Run参数对应的方法中

var versionCmd = &cobra.Command{
Use: "version",
Short: "A brief description of your command",
Long: `A longer description that spans multiple lines and likely contains examples
and 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 files
to quickly create a Cobra application.`,
Run: func(cmd *cobra.Command, args []string) {
fmt.Println("version called")
},
}

3.添加flag

3.1.添加局部flag

在 version.go 文件的 init 函数中添加 局部flag

func init() {
rootCmd.AddCommand(versionCmd)
versionCmd.Flags().BoolP("test", "t", false, "test")
}

执行命令

> ./demo version -h

Usage:
demo version [flags] Flags:
-h, --help help for version
-t, --test test Global Flags:
--config string config file (default is $HOME/.demo.yaml)

4. flag赋值

如果需要使用 全局flag 或者 局部flag,需要在合适的作用域内定义变量存储 flag 值,以便 flag 可在特定作用域内生效。

4.1.使用全局flag

让一个 flag 对所有命令生效,需要在 root.go 文件中创建一个变量存储 flag 值。

如需要定义一个全局flag name:

1.在root.go 文件中添加一个变量name

var name string

2.在init函数中添加全局flag,将flag值存储到变量name中

rootCmd.PersistentFlags().StringVar(&name, "name", "", "set name")

3.在子命令version的Run方法中输出name
Run: func(cmd *cobra.Command, args []string) {
fmt.Println("name is: ", name)
} 4.执行命令
./demo version --name wfl
输出:
name is: wfl

4.2.使用局部flag

让一个 flag 对某个命令生效,需要在该命令文件中创建一个变量存储 flag 值。

如需要给version命令定义一个局部flag name:

1.定义变量sunsine
var sunshine string 2.在version.go的init函数中添加flag
versionCmd.Flags().StringVarP(&sunshine, "sunshine", "s", "false", "you are my sunshine") 3.在子命令version.go的Run方法中输出
Run: func(cmd *cobra.Command, args []string) {
fmt.Println("name is: ", name)
fmt.Println("sunshine is: ", sunshine)
} 4.执行命令
./demo version --name wfl --sunshine wfl
输出:
name is: wfl
sunshine is: wfl

问题:

flags 存储到本地变量当中,那么其他命令是不是也可以用某个命令的 局部flag 呢?

答:不可以。局部flag虽然是定义在某个命令文件中作为局部变量,cmd 文件夹下的其他文件可以访问这个变量,但是其他命令如果没有定义自己的 局部flag 获取相同 flag 值的话,获取到的值是该局部变量的零值。

1.添加一个新命令helloworld
> cobra add helloworld 2.输出sunshine值
Run: func(cmd *cobra.Command, args []string) {
fmt.Println("sunshine is: ", sunshine)
} 3.执行命令
> ./demo helloworld --sunshine wfl
Error: unknown flag: --sunshine
输出错误未知flag。
原因就是该命令并未定义局部flagsunshine

4.3.必填flag

默认情况下,flag是optional(选填),若flag为必填,则需要做如下设置

如将version命令下的sunshine flag设置为必填

1.init文件中增加flag定义
versionCmd.Flags().StringVarP(&sunshine, "sunshine", "s", "", "you are my sunshine")
versionCmd.MarkFlagRequired("sunshine") 2.执行
> ./demo version 3.输出
Error: required flag(s) "sunshine" not set
说明必须要设置flag sunshine 4.传入sunshineflag
> ./demo version --sunshine wfl
输出: sunshine is: wfl

5. 嵌套子命令

cobra 的命令行工具可以创建嵌套子命令。使用 cobra add -p "父命令Cmd"。

比如

1.给version命令添加一个子命令show
> cobra add show -p "versionCmd" 2.在cobra生成的show.go文件的init方法中,自动将showCmd添加到versionCmd下作为子命令
func init() {
versionCmd.AddCommand(showCmd)
} 3.执行嵌套子命令
> ./demo version show
show called

6. 获取命令行参数值

cobra 常用的参数配置校验器如下:

MinimumNArgs(int) 当参数数目低于配置的最小参数个数时报错
MaximumNArgs(int) 当参数数目大于配置的最大参数个数时报错
ExactArgs(int) 如果参数数目不是配置的参数个数时报错
NoArgs 没有参数则报错

类似 git clone URL 这种类型的命令行,URL 为传给 clone 命令的参数

获取URL的值,可以从 args 参数中直接取出

举例:

1.添加一个命令path
> cobra add path 2.设置该命令需要且仅需要一个参数,并在Run方法中取出参数
var pathCmd = &cobra.Command{
Use: "path [path]",
Short: "A brief description of your command",
Long: `A longer description that spans multiple lines and likely contains examples
and 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 files
to quickly create a Cobra application.`,
Args: cobra.ExactArgs(1),
Run: func(cmd *cobra.Command, args []string) {
fmt.Println("path called")
fmt.Println("path:", args[0])
},
} 3. 执行命令并输出
> ./demo path /home
path: /home

go cobra实例讲解的更多相关文章

  1. float实例讲解

    float实例讲解 float是个强大的属性,在实际前端开发过程中,人们经常拿它来进行布局,但有时,使用的不好,也麻烦多多啊. 比如,现在我们要实现一个两列布局,左边的列,宽度固定:右边的列,宽度自动 ...

  2. S3C2440上RTC时钟驱动开发实例讲解(转载)

    嵌入式Linux之我行,主要讲述和总结了本人在学习嵌入式linux中的每个步骤.一为总结经验,二希望能给想入门嵌入式Linux的朋友提供方便.如有错误之处,谢请指正. 共享资源,欢迎转载:http:/ ...

  3. 实例讲解Oracle数据库设置默认表空间问题

    实例讲解Oracle数据库设置默认表空间问题   实例讲解Oracle数据库设置默认表空间问题,阅读实例讲解Oracle数据库设置默认表空间问题,DBA们经常会遇到一个这样令人头疼的问题:不知道谁在O ...

  4. 基于tcpdump实例讲解TCP/IP协议

    前言 虽然网络编程的socket大家很多都会操作,但是很多还是不熟悉socket编程中,底层TCP/IP协议的交互过程,本文会一个简单的客户端程序和服务端程序的交互过程,使用tcpdump抓包,实例讲 ...

  5. makefile基础实例讲解 分类: C/C++ 2015-03-16 10:11 66人阅读 评论(0) 收藏

    一.makefile简介 定义:makefile定义了软件开发过程中,项目工程编译链.接接的方法和规则. 产生:由IDE自动生成或者开发者手动书写. 作用:Unix(MAC OS.Solars)和Li ...

  6. 实例讲解Linux系统中硬链接与软链接的创建

    导读 Linux链接分两种,一种被称为硬链接(Hard Link),另一种被称为符号链接(Symbolic Link).默认情况下,ln命令产生硬链接.硬链接与软链接的区别从根本上要从Inode节点说 ...

  7. spring事务传播机制实例讲解

    http://kingj.iteye.com/blog/1680350   spring事务传播机制实例讲解 博客分类:   spring java历险     天温习spring的事务处理机制,总结 ...

  8. 实例讲解MySQL联合查询

    好了终于贴完了MySQL联合查询的内容了,加上上一篇一共2篇,都是我转载的,实例讲解MySQL联合查询.那下面就具体讲讲简单的JOIN的用法了.首先我们假设有2个表A和B,他们的表结构和字段分别为: ...

  9. Html代码seo优化最佳布局实例讲解

    搜索引擎对html代码是非常优化的,所以html的优化是做好推广的第一步.一个符合seo规则的代码大体如下界面所示. 1.<!–木庄网络博客–> 这个东西是些页面注释的,可以在这里加我的& ...

  10. 【MySQL】分页查询实例讲解

    MySQL分页查询实例讲解 1. 前言 本文描述了团队在工作中遇到的一个MySQL分页查询问题,顺带讲解相关知识点,为后来者鉴.本文的重点不是"怎样"优化表结构和SQL语句,而是探 ...

随机推荐

  1. Qt数据库应用1-数据导入导出csv

    一.前言 在经历过大大小小十几个甚至几十个纯QtWidget项目后,涉及到数据库相关的项目,几乎都有一个需求,将少量的信息数据比如设备信息.防区信息等,导出到文件保存好,然后用户可以打开该表格进行编辑 ...

  2. Anaconda下载以前的旧版本

    由于Anaconda新的版本,可能不太适合我们当前开发,我们需要下载历史版本. 可以尝试从两个地方下载:1.推荐从 "清华大学开源软件镜像站" 下载:https://mirrors ...

  3. 我的新书《C#上位机开发实战指南》出版了

    -Begin- 大家好!我是付工. 2022年的时候,我萌生了编写一本上位机书籍的想法,希望能给更多的上位机学习者提供一些帮助,经历了2年多的时间,今年的8月份,这本书终于出版了. 初衷 十年前,我也 ...

  4. Java基础总结,超级全的面试题-copy

    1. static关键字是什么意思?Java 中是否可以覆盖(override)一个 private 或者是 static 的方法?是否可以在 static 环境中访问非static 变量? stat ...

  5. Linux操作系统基础知识

    一.输入法的切换Application ----> System Tools ----> Settings ----> Rejino&language ----> In ...

  6. ZUC-S盒输入输出测试

    问题 实现以二进制.十进制.十六进制的形式输入,经过S盒,输出十六进制 输入: 1.二进制:10001010010011110000011110111101 2.十进制:2320435133 3.十六 ...

  7. ORACLE 中报ORA-30926 无法在源表中获得稳定的行的处理

    在库存处理的业务中有这么一个场景,一张处方划价单进行库存扣减处理,如果此单据同一商品有两行以上,同时扣减同一行库存记录,使用MERGE INTO批量更新是就会报错:ORA-30926 无法在源表中获得 ...

  8. 新年开篇:在本地部署DeepSeek大模型实现联网增强的AI应用

    在本地部署DeepSeek大模型实现联网增强的AI应用 一.前言 在本地部署大语言模型(LLM)并赋予其联网能力,是当前AI应用开发的重要方向.本文将基于Microsoft Semantic Kern ...

  9. 通过virtual-install安装

    命令行 [root@kvm1 ~]# qemu-img create -f qcow2 centos6.10b.qcow2 10G Formatting 'vm1-disk1.qcow2', fmt= ...

  10. .Net Core 项目启动方式

    本文篇幅较小,讲解如何通过命令行启动项目 接着上一章的Core WebApi(https://www.cnblogs.com/zousc/p/12420998.html),我们已经有了Hello这个控 ...