go 命令行框架cobra

go 命令行框架cobra

go 拉取依赖包go get github.com/spf13/cobra

认识spf13/cobra-cli. cobra 命令行框架在golang中的地位也算得上是大明星级别。像k8s,docker都有使用这个框架构建自己命令行这块的功能.

最最最简单的开始----使用命令行工具cobra-cli来初始化你的demo

cobra-cli init 初始化你的demo.后面可以加目录名,不加就是当前目录下创建一个main.go 和cmd目录(如果这时你main.go里写了东西,先备份再初始化)。cmd目录cobra-cli是用来储存子命令的地方,后面我们手动写的时候这个就不重要了

cobra-cli add options 添加一个子命令。例如你的demo名叫demo,你需要实现一个demo put xxxx的功能。cobra-cli add put

cobra-cli add options -p parent_optionCmd 子命令添加子命令。例如给上面的put加一个子命令为single cobra-cli add single -p putCmd 这里p参数为指定该命令的父命令,需要加后缀Cmd,因为-p参数实际是代码中的参数名,而cobra-cli自动创建命令时参数名为格式为xxxxCmd

编译demo. 运行demo 带-h查看cobra-cli生成的效果

认识cobra-cli框架下的命令行命令构造

每一个命令可以说是独立的,但是整个程序得有一个根命令rootCmd,这个rootCmd和其它命令性质都是一样的(都可以具备独立的flagset,usage)。只不过它的位置是“树根”而已
请添加图片描述

参数

  • 兼容golang 标准库flag.FlagSet
  • 能够设置必备参数(必填的参数)
//以putCmd为例
/*
Copyright © 2024 NAME HERE <EMAIL ADDRESS>
*/
package cmd

import (
	"fmt"
	"log"

	"github.com/spf13/cobra"
)

// putCmd represents the put command
var putCmd = &cobra.Command{
	Use:   "put",//子命令的具体名字
	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("put called")
	},
}

func init() {
	rootCmd.AddCommand(putCmd)//将putCmd添加到rootCmd的分支上去。成为rootCmd的子命令
	//为put命令添加参数,结尾有P的为带缩写的参数。添加的时候看清楚你添加的命令是哪一个,别搞混了搞到rootCmd上去了
	fs := flag.NewFlagSet("put", flag.ExitOnError)
	putCmd.Flags().AddGoFlagSet(fs)//添加go标准库中的flagset至put命令中
	putCmd.Flags().String("type", "", "input type")
	err := putCmd.MarkFlagRequired("type")//为这项命令添加必备参数。
	if err != nil {
		log.Fatalln(err)
	}
	// Here you will define your flags and configuration settings.

	// Cobra supports Persistent Flags which will work for this command
	// and all subcommands, e.g.:
	// putCmd.PersistentFlags().String("foo", "", "A help for foo")

	// Cobra supports local flags which will only run when this command
	// is called directly, e.g.:
	// putCmd.Flags().BoolP("toggle", "t", false, "Help message for toggle")
}

开始使用spf13/cobra框架自行编写命令行工具

一个简单的开始

package main

import (
	"fmt"
	"log"

	"github.com/spf13/cobra"
)
//你的子命令都可以通过这种方式创建,这么做可以操作的空间很多
func NewCommand() *cobra.Command {
	//这一块你可以做一些这个命令需要的变量初始化,rune函数里面就可以直接用了
	var cmd = cobra.Command{
		Use:                "demo",
		Short:              "this is a simple sample",
		RunE: func(cmd *cobra.Command, args []string) (err error) {//与rune 对应的还有run,两个都一样,只是返不返回错误的区别,我个人喜欢返回错误出去,最后统一处理。你可以根据自己喜好自行选者
			fmt.Println("this is an example start")
			return
		},
	}
	//这里你可以做些命令行参数绑定什么的
	return &cmd
}

func main() {
	cmd := NewCommand()
	err := cmd.Execute()
	if err != nil {
		log.Fatalln(err.Error())
	}
}

自行控制参数解析,你也可以不用cobra框架,单纯用参数工具pflag(cobra依赖pflag解析参数,你如果依赖了cobra,就不用再go get github.com/spf13/pflag)

package main

import (
	"demo/options"
	"log"
	"time"

	"github.com/spf13/cobra"
	"github.com/spf13/pflag"
)

func getCommandFlags(f *pflag.FlagSet) {
	f.String("type", "", "input type ")
	f.Duration("ttl", time.Second, "ttl")
}
func NewCommand() *cobra.Command {
	var cmd = cobra.Command{
		Use:                "demo",
		Short:              "this is a simple sample",
		DisableFlagParsing: true,//使用我们自带的pflag.FlagSet
		SilenceUsage:       true,//参数传入错误时不会把usage信息弹出来
		RunE: func(cmd *cobra.Command, args []string) (err error) {
			pf := pflag.NewFlagSet("demo", pflag.ContinueOnError)
			getCommandFlags(pf)
			cmd.Flags().AddFlagSet(pf)
			help := pf.BoolP("help", "h", false, "--help")
			err = pf.Parse(args)
			if err == nil {
				if *help {
					return cmd.Help()
				}
			}
			return
		},
	}
	cmd.AddCommand(options.NewPutCommand())
	return &cmd
}

func main() {
	cmd := NewCommand()
	err := cmd.Execute()
	if err != nil {
		log.Fatalln(err.Error())
	}
}

参数解析设置别名

我觉得这是pflag最哇塞的一个功能

func setalias(f *pflag.FlagSet) {
//将所有参数名带-的,使用.也是一样的识别,这里name是参数原始名,返回的是别名。
	f.SetNormalizeFunc(func(f *pflag.FlagSet, name string) pflag.NormalizedName {
		return pflag.NormalizedName(strings.ReplaceAll(name, "-", "."))
	})
}

最终演示代码

package main

import (
	"demo/options"
	"fmt"
	"log"
	"net"
	"strings"
	"time"

	"github.com/spf13/cobra"
	"github.com/spf13/pflag"
)

var (
	flag_result struct {
		_type string
		ttl   time.Duration
		ip    net.IP
	}
)

func getCommandFlags(f *pflag.FlagSet) {
	f.StringVar(&flag_result._type, "type", "", "input type ")
	f.DurationVar(&flag_result.ttl, "ttl", time.Second, "ttl")
	f.IPVar(&flag_result.ip, "net-ip4", nil, "ip address")
}
func setalias(f *pflag.FlagSet) {
	f.SetNormalizeFunc(func(f *pflag.FlagSet, name string) pflag.NormalizedName {
		return pflag.NormalizedName(strings.ReplaceAll(name, "-", "."))
	})
}
func NewCommand() *cobra.Command {
	var cmd = cobra.Command{
		Use:                "demo",
		Short:              "this is a simple sample",
		DisableFlagParsing: true,
		SilenceUsage:       true,
		RunE: func(cmd *cobra.Command, args []string) (err error) {
			pf := pflag.NewFlagSet("demo", pflag.ContinueOnError)
			getCommandFlags(pf)
			setalias(pf)
			cmd.Flags().AddFlagSet(pf)
			help := pf.BoolP("help", "h", false, "--help")
			err = pf.Parse(args)
			if err == nil {
				if *help {
					return cmd.Help()
				}
				fmt.Println(flag_result._type, flag_result.ttl, flag_result.ip)
			}
			return
		},
	}
	cmd.AddCommand(options.NewPutCommand())
	return &cmd
}

func main() {
	cmd := NewCommand()
	err := cmd.Execute()
	if err != nil {
		log.Fatalln(err.Error())
	}
}

请添加图片描述
请添加图片描述
请添加图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/424836.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

四种策略改进的麻雀算法!效果起飞!你确定不来看看吗?

声明&#xff1a;文章是从本人公众号中复制而来&#xff0c;因此&#xff0c;想最新最快了解各类智能优化算法及其改进的朋友&#xff0c;可关注我的公众号&#xff1a;强盛机器学习&#xff0c;不定期会有很多免费代码分享~ 目录 效果展示&#xff1a; 改进策略详解&#…

C语言——指针的进阶——第1篇——(第26篇)

坚持就是胜利 文章目录 一、字符指针1、面试题 二、指针数组三、数组指针1、数组指针的定义2、&数组名 VS 数组名3、数组指针的使用&#xff08;1&#xff09;二维数组传参&#xff0c;形参是 二维数组 的形式&#xff08;2&#xff09;二维数组传参&#xff0c;形参是 指针…

django的模板渲染中的【高级定制】:按数据下标id来提取数据

需求&#xff1a; 1&#xff1a;在一个页面中显示一张数据表的数据 2&#xff1a;不能使用遍历的方式 3&#xff1a;页面中的数据允许通过admin后台来进行修改 4&#xff1a;把一张数据表的某些内容渲染到[xxx.html]页面 5&#xff1a;如公司的新商品页面&#xff0c;已有固定的…

python进阶:可迭代对象和迭代器

一、Iterable&#xff08;可迭代对象&#xff09; 1、可迭代对象&#xff1a;能够进行迭代操作的对象。 可以理解为&#xff1a;能够使用for循环遍历的都是可迭代对象&#xff1b;**所有的可迭代对象&#xff0c;偶可以用内置函数iter转换为迭代器** 2、可迭代对象包括&…

Linux文本处理三剑客:awk(常用匹配模式)

在Linux操作系统中&#xff0c;grep、sed、awk被称为文本操作“三剑客”&#xff0c;上三期中&#xff0c;我们将详细介绍grep、sed、awk的基本使用方法&#xff0c;希望能够帮助到有需要的朋友。 1、前言 awk作为一门编程语言还有很多内容&#xff0c;我们继续学习awk。 网…

快速解决maven依赖冲突

我们在开发过程中经常出现maven依赖冲突&#xff0c;或者maven版本不匹配的情况&#xff0c;我们可以使用阿里云原生脚手架来做maven管理&#xff0c;添加需要的组件&#xff0c;然后点击获取代码&#xff0c;就可以获得对应的依赖文件。

【C语言】InfiniBand驱动mlx4_init和mlx4_cleanup

一、中文注释 Linux内核模块的初始化和清理过程&#xff0c;针对一个称为mlx4的网络设备驱动。以下是代码的逐行中文注释&#xff1a; static int __init mlx4_init(void) {int ret;if (mlx4_verify_params())return -EINVAL; // 检查设备参数是否有效&#xff0c;无效则返回…

.idea文件详解

.idea文件的作用&#xff1a; .idea文件夹是存储IntelliJ IDEA项目的配置信息&#xff0c;主要内容有IntelliJ IDEA项目本身的一些编译配置、文件编码信息、jar包的数据源和相关的插件配置信息。一般用git做版本控制的时候会把.idea文件夹排除&#xff0c;因为这个文件下保存的…

ABAP - SALV教程08 列设置热点及绑定点击事件

实现思路&#xff1a;将列设置成热点&#xff0c;热点列是可点击的&#xff0c;再给SALV实例对象注册点击事件即可&#xff0c;一般作用于点击单号跳转到前台等功能 "设置热点方法METHODS:set_hotspot CHANGING co_alv TYPE REF TO cl_salv_table...."事件处理方法M…

OSCP靶场--Hepet

OSCP靶场–Hepet 考点(1.邮件获取 2.msf恶意宏文档制作 3. 邮件投递恶意宏文档 4.服务配置不当提权) 1.nmap扫描 ┌──(root㉿kali)-[~/Desktop] └─# nmap -sV -sC -p- 192.168.188.140 --min-rate 2000 Starting Nmap 7.92 ( https://nmap.org ) at 2024-03-01 05:46 ES…

【网上商城系统的设计与开发】

目录 1.实训概况 1 1.1 实训题目 1 1.2实训时间 1 1.3实训目的 1 1.4 实训环境 1 1.5 实训内容 2 1.6 进度安排 3 2.需求分析 5 2.1 功能需求分析 5 2.1.1用户需求分析 5 2.2.2网站前台需求 5 2.2.3网站后台需求 6 2.2 可行性分析 7 2.2.1社会可行性 7 2.2.2技术可行性 8 3.系统…

通过多进程并发方式(fork)实现服务器(注意要回收子进程)

以下内容为视频学习记录。 1、父进程accept后返回的文件描述符为cfd以及用于创建连接的lfd; 调用fork()创建子进程后&#xff0c;子进程继承cfd,lfd&#xff0c;通过该cfd与连接过来的客户端通信,lfd对子进程来说没用&#xff0c;可以直接close(lfd); 对于父进程来说&#x…

如何利用ChatGPT搞科研?论文检索、写作、基金润色、数据分析、科研绘图(全球地图、植被图、箱型图、雷达图、玫瑰图、气泡图、森林图等)

以ChatGPT、LLaMA、Gemini、DALLE、Midjourney、Stable Diffusion、星火大模型、文心一言、千问为代表AI大语言模型带来了新一波人工智能浪潮&#xff0c;可以面向科研选题、思维导图、数据清洗、统计分析、高级编程、代码调试、算法学习、论文检索、写作、翻译、润色、文献辅助…

2023天津公租房网上登记流程图,注册到信息填写

2023年天津市公共租赁住房网上登记流程图 小编为大家整理了天津市公共租赁住房网上登记流程&#xff0c;从登记到填写信息。 想要体验的朋友请看一下。 申请天津公共租赁住房时拒绝申报家庭情况会怎样&#xff1f; 天津市住房保障家庭在享受住房保障期间&#xff0c;如在应申…

安装 node 错误的配置环境变量之后使用 npm 报错,更换淘宝镜像 (cnpm)

安装 node 错误的配置环境变量之后使用 npm 报错&#xff0c;更换淘宝镜像 (cnpm) node:internal/modules/cjs/loader:1147 throw err; ^ Error: Cannot find module ‘F:\ACodeTools\Node\node_modules\npm\bin\node_modules\npm\bin\npm-cli.js’ at Module._resolveFilename…

JVM(6)

JMM JVM定义了一种Java内存模型来屏蔽掉各种硬件和操作系统的内存访问差异,以实现让Java程序在各种平台下都能达到一致的内存访问效果.在此之前,C/C直接使用物理硬件和操作系统的内存模型,因此,会由于不同平台下的内存模型差异,有可能导致程序在一套平台上并发完全正常,而在另…

多输入多输出 | MATLAB实现GWO-Elman灰狼优化循环神经网络多输入多输出预测

多输入多输出 | MATLAB实现GWO-Elman灰狼优化循环神经网络多输入多输出预测 目录 多输入多输出 | MATLAB实现GWO-Elman灰狼优化循环神经网络多输入多输出预测预测效果基本介绍程序设计往期精彩参考资料 预测效果 基本介绍 Matlab实现GWO-Elman灰狼优化循环神经网络多输入多输出…

手把手教测试,全网内容最全有深度-jmeter-Flow Control Action

5.1.7.6.Flow Control Action(测试活动) Logical Action on Thread&#xff1a; Pause 暂停&#xff0c;配合 Duration 一起使用&#xff1b;Duration(milliseconds) 延迟时间&#xff0c;单位是毫秒 Start Next Thread Loop 开始本线程下一次循环 设置线程组线程数2&#xff…

(资源篇)2025届暑假实习春招全攻略路线

绝对的全攻略&#xff0c;资源完善程度绝对的全网唯一。 觉得有帮助的&#xff1a;随手一键三连关注就是对up主最大的激励。 绝对的宝藏up主&#xff01;&#xff01;&#xff01;&#xff0c;up主每天都会进行更新视频&#xff0c;算法视频or校招信息or八股讲解。 【暴躁老…

位运算第二弹

力扣191.位1的个数 public class Solution {// you need to treat n as an unsigned valuepublic int hammingWeight(int n) {int ret0;while(n!0){n(n&n-1);ret;}return ret;} } 推荐是自己去手动推一下&#xff0c;深刻理解一下&#xff0c;什么叫做最右侧的1。 力扣338.…