go语言命令行工具cobra

news2024/11/24 15:03:12

go语言命令行工具cobra

1、Cobra 介绍

Cobra 是关于 golang 的一个命令行解析库,用它能够快速创建功能强大的 cli 应用程序和命令行工具。

cobra既是一个用于创建强大现代CLI应用程序的库,也是一个生成应用程序和命令文件的程序。cobra被用在很多

go语言的项目中,比如 Kubernetes、Docker、Istio、ETCD、Hugo、Github CLI等等。

我们平常用到命令:git commit -m “message”,docker containter start 等都可以用 cobra 来实现。

Cobra 官网:https://cobra.dev/

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

2、功能特性介绍

  • 很多子命令的CLIS: 比如 app server、app fetch 等
  • 支持嵌套子命令(sub-command)
  • 轻松完成应用程序和命令的创建:cobra init appname 和 cobra add cmdname
  • 为应用程序生成 man 手册
  • 全局、本地和级联 flag
  • 为 shell 程序完成自动提示(bash,zsh,fish, powershell etc.)
  • 支持命令行别名,可以帮助你更容易更改内容而不破坏他们
  • 灵活定义自己的help、usage信息
  • 可选集成 viper 配置管理工具库

3、Cobra命令结构说明

Cobra 命令结构由3部分组成:

commands、arguments 和 flags

  • commands:

    命令行,代表行为动作,要执行的一个动作。每个命令还可以包含子命令,分为:rootCmd 和 subCmd。程

    序中具体对象是 cobra.Command{},这个是根命令;子命令(subCmd)用 rootCmd.AddCommand() 添加,

    子命令通常也会单独存一个文件,并通过一个全局变量让 rootCmd 可以 add 它。

  • arguments:

    命令行参数,通常是 []string 表示。

  • flags:

    命令行选项。对 command 进一步的控制。通常用一短横 - 或者两短横 -- 标识,程序中读取存储在变量

    中。

cobra 命令行格式:

APPNAME VERB NOUN --ADJECTIVE
APPNEM COMMAND ARG --FLAG

例子说明:

# server代表command,port代表flag
hugo server --port=1313
# clone代表command,URL代表argument,bare代表flag
git clone URL --bare

4、Cobra基本使用方法

安装 cobra:

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

安装 cobra-cli:

$ go get github.com/spf13/cobra-cli
$ go install github.com/spf13/cobra-cli

可以用 cobra-cli -h 来查看 cobra 命令的一些用法。

$ cobra-cli -h
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.

Usage:
  cobra-cli [command]

Available Commands:
  add         Add a command to a Cobra Application
  completion  Generate the autocompletion script for the specified shell
  help        Help about any command
  init        Initialize a Cobra Application

Flags:
  -a, --author string    author name for copyright attribution (default "YOUR NAME")
      --config string    config file (default is $HOME/.cobra.yaml)
  -h, --help             help for cobra-cli
  -l, --license string   name of license for the project
      --viper            use Viper for configuration

Use "cobra-cli [command] --help" for more information about a command.

4.1 init命令初始化应用程序

使用命令 cobra-cli init 来创建第一个应用程序,这个命令也是初始化一个应用程序的项目框架,具体的过程:

$ mkdir go-cobra
$ go mod init proj
$ cobra-cli init
Your Cobra application is ready at
......\go-cobra

自动生成了如下目录的程序:

在这里插入图片描述

程序代码如下:

main.go

/*
Copyright © 2023 NAME HERE <EMAIL ADDRESS>

*/
package main

import "proj/cmd"

func main() {
	cmd.Execute()
}

cmd/root.go

/*
Copyright © 2023 NAME HERE <EMAIL ADDRESS>

*/
package cmd

import (
	"os"

	"github.com/spf13/cobra"
)



// rootCmd represents the base command when called without any subcommands
var rootCmd = &cobra.Command{
	Use:   "proj",
	Short: "A brief description of your application",
	Long: `A longer description that spans multiple lines and likely contains
examples 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 files
to quickly create a Cobra application.`,
	// Uncomment the following line if your bare application
	// has an action associated with it:
	// Run: func(cmd *cobra.Command, args []string) { },
}

// Execute adds all child commands to the root command and sets flags appropriately.
// This is called by main.main(). It only needs to happen once to the rootCmd.
func Execute() {
	err := rootCmd.Execute()
	if err != nil {
		os.Exit(1)
	}
}

func init() {
	// Here you will define your flags and configuration settings.
	// Cobra supports persistent flags, which, if defined here,
	// will be global for your application.

	// rootCmd.PersistentFlags().StringVar(&cfgFile, "config", "", "config file (default is $HOME/.proj.yaml)")

	// Cobra also supports local flags, which will only run
	// when this action is called directly.
	rootCmd.Flags().BoolP("toggle", "t", false, "Help message for toggle")
}

启动运行:

$ go run main.go
A longer description that spans multiple lines and likely contains
examples 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 files
to quickly create a Cobra application.

可以看出,用 cobra-cli init 命令初始化的项目, 生成了一个初始化的应用框架,但是没有任何逻辑功能,仅仅输

出一些描述性信息。

这个程序里,最重要的是 cmd/root.go 里的 rootCmd = &cobra.Command{} 这行程序,这里定义命令动作。

程序里的 init() 函数是对命令行的配置。

4.2 add 生成子命令subCmd

上面我们用 cobra-cli init 创建了应用程序框架,在程序 cmd/root.go 里有一个根命令 rootCmd,也就是说 init 命

令创建了一个根命令。执行 command 命令是 &cobra.Command{} 里的 Run 方法。

用 cobra-cli add 来为 rootCmd 创建一个子命令。

下面添加两个命令 ping 和 cat,这个子命令通常在一个单独的文件里。

$ cobra-cli add ping
ping created at ......\go-cobra
$ cobra-cli add cat 
cat created at ......\go-cobra

自动生成了如下目录的程序:

在这里插入图片描述

查看文件:

/*
Copyright © 2023 NAME HERE <EMAIL ADDRESS>

*/
package cmd

import (
	"fmt"

	"github.com/spf13/cobra"
)

// pingCmd represents the ping command
var pingCmd = &cobra.Command{
	Use:   "ping",
	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("ping called")
	},
}

func init() {
	rootCmd.AddCommand(pingCmd)

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

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

	// Cobra supports local flags which will only run when this command
	// is called directly, e.g.:
	// pingCmd.Flags().BoolP("toggle", "t", false, "Help message for toggle")
}
/*
Copyright © 2023 NAME HERE <EMAIL ADDRESS>

*/
package cmd

import (
	"fmt"

	"github.com/spf13/cobra"
)

// catCmd represents the cat command
var catCmd = &cobra.Command{
	Use:   "cat",
	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("cat called")
	},
}

func init() {
	rootCmd.AddCommand(catCmd)

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

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

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

运行:

$ go run main.go --help
# 等价
$ go run main.go
A longer description that spans multiple lines and likely contains
examples 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 files
to quickly create a Cobra application.

Usage:
  proj [command]

Available Commands:
  cat         A brief description of your command
  completion  Generate the autocompletion script for the specified shell
  help        Help about any command
  ping        A brief description of your command

Flags:
  -h, --help     help for proj
  -t, --toggle   Help message for toggle

Use "proj [command] --help" for more information about a command.

ping 和 cat 已经被集成到 root.go 中。

$ go run main.go ping
ping called

$ go run main.go cat
cat called

也可以自己编写文件然后进行手动添加。

子命令和根命令的关系一般通过程序 rootCmd.AddCommand() 方法确定。在程序里可以看到它在 init() 函数里。

Run 方法里可以添加自己需要实现的程序,一般这里的程序都是其他 package 里完成了具体逻辑,然后 Run 方法

里在调用这些程序。

4.3 给command添加flags

flag 命令行选项,也叫标识,对command命令行为的进一步指示操作。

用这个标识可以给 command 添加一些可选项。

根据 flag 选项作用范围不同,可以分为 2 类:

  • Persistent Flags,持久化的flag,全局范围

    如果设置全局范围的flag,可以用这个来设置。它既可以给根命令设置选项值,也可以给子命令设置选项值。

  • Local Flags,局部flag

    只对指定的command生效,比如某个子命令的 flag。

因为 flag 标识是在命令行后面不同位置使用,所以我们要在方法外定义一个变量,来分配存储使用这个标识符。

下面我们给 cat 命令添加命令行选项来实现全局 flag 和局部 flag。

4.3.1 全局flag

cmd/root.go 文件中添加一个变量 configFile

var configFile string

cmd/root.go 的 init() 函数中添加全局 flag,把 flag 值存储到变量 configFile 中。也就是读取命令行

–configfile 这个 flag 设置的值,然后赋值给程序里变量 configFile。

// 添加全局flag
rootCmd.PersistentFlags().StringVar(&configFile, "configfile", "$HOME/app.conf", "config file (default is $HOME/app.conf)")

在文件 cmd/cat.go 中的 catCmd(子命令) 里 Run 方法输出 configFile 值:

Run: func(cmd *cobra.Command, args []string) {
   fmt.Println("cat called")
   // 打印输出 name
   fmt.Println("print persistent flag configFile: ", configFile)
},

测试运行程序:

$ go run main.go cat -h
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.

Usage:
  proj cat [flags]

Flags:
  -h, --help   help for cat

Global Flags:
      --configfile string   config file (default is $HOME/app.conf) (default "$HOME/app.conf")
$ go run main.go cat --configfile /opt/app.yaml
cat called
print persistent flag configFile:  /opt/app.yaml

当然也可以先编译 go build -o main.exe,我用的win,然后在运行测试程序:

$ go build -o main.exe
$ main.exe cat --configfile /opt/app.yaml
cat called
print persistent flag configFile:  /opt/app.yaml

Persistent flag 的读取方法:

// arg1:存储变量
// arg2:设置长flag名,这里name显示--name
// arg3:设置短flag名,这里n显示-n,一般与上面对应
// arg4:默认值,这里设置为""
// arg5:flag的一些说明信息
PersistentFlags().StringVarP(&name, "name", "n", "", "Set one name")

// 与上面用法基本相同,只是没有短flag设置
PersistentFlags().StringVar(&name, "name", "", "Set one name")

// 直接设置flag名,arg1:flag名,arg2:默认值,arg3:说明
PersistentFlags().String("foo", "", "A help for foo")

4.3.2 局部flag

一个 flag 赋值给本地变量,只能对指定的 command 生效。

我们在 cmd/ping.go 中测试局部 flag。

cmd/ping.go 文件中定义变量 ip,存储这个 flag 值。

// 定义局部flag
var ip string

cmd/ping.go 中的 init() 中添加下面代码,把值存储到 ip 上。

pingCmd.Flags().StringVarP(&ip, "ip", "i", "127.0.0.1", "ip")

在 pingCmd.Command{} 获取该值:

Run: func(cmd *cobra.Command, args []string) {
		fmt.Println("ping called")
		// 打印输出 name
		fmt.Println("print persistent flag configFile: ", configFile)
		// 打印输出local flag: dsn
		fmt.Println("(local flag) print ip: ", ip)
	}

测试运行:

$ go run main.go ping -h
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.

Usage:
  proj ping [flags]

Flags:
  -h, --help        help for ping
  -i, --ip string   ip (default "127.0.0.1")

Global Flags:
      --configfile string   config file (default is $HOME/app.conf) (default "$HOME/app.conf")
$ go run main.go ping --ip "192.168.164.195" 
ping called
print persistent flag configFile:  $HOME/app.conf
(local flag) print ip:  192.168.164.195
# 可以读取全局flag
$ go run main.go ping --ip "192.168.164.195" --configfile /opt/app.yaml
ping called
print persistent flag configFile:  /opt/app.yaml
(local flag) print ip:  192.168.164.195

说明:local flag 局部选项,只能作用于指定的 command。

local flag 的读取方法:

// arg1:存储变量,
// arg2:设置长flag名,这里name显示--name,
// arg3:设置短flag名,这里n显示-n,一般与上面对应
// arg4:默认值,这里设置为""
// arg5:flag的一些说明信息
// 方法(1)
Flags().StringVarP(&name, "name", "n", "", "Set one name")

// 与上面方法(1)用法基本相同,只是没有短flag设置
Flags().StringVar(&name, "name", "", "Set one name")

// 直接设置flag名,arg1:flag名,arg2:默认值,arg3:说明
Flags().String("foo", "", "A help for foo")

// 与上面方法(1)用法基本相同,除了第一个没有变量读取参数
Flags().StringP("toggle", "t", false, "Help message for toggle")

4.3.3 设置flag必填项

比如给 cmd/ping.go 的 ip 这个 flag 设置必选项:

pingCmd.Flags().StringVarP(&ip, "ip", "i", "127.0.0.1", "ip")
// 把ip设置为必选项
pingCmd.MarkFlagRequired("ip")

flag 不设置 ip,运行程序:go run main.go ping,报错:

$ go run main.go ping
Error: required flag(s) "ip" not set

加上 ip 运行,go run main.go ping --ip 192.168.164.195,正常输出:

$ go run main.go ping --ip 192.168.164.195
ping called
print persistent flag configFile:  $HOME/app.conf
(local flag) print ip:  192.168.164.195

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

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")

4.3.4 绑定配置

还可以绑定配置到 flags 上,用 viper。

我们可以在 init() 方法中添加绑定 flag 程序。

cmd/root.go 里面,添加如下内容:

var author string
func init() {
	rootCmd.Flags().BoolP("toggle", "t", false, "Help message for toggle")
	// 添加全局flag
	rootCmd.PersistentFlags().StringVar(&configFile, "configfile", "$HOME/app.conf", "config file (default is $HOME/app.conf)")
	rootCmd.PersistentFlags().StringVar(&author, "author", "zhangsan", "Author name for copyright attribution")
	viper.BindPFlag("author", rootCmd.PersistentFlags().Lookup("author"))
}

cmd/ping.go 里面读取输出:

Run: func(cmd *cobra.Command, args []string) {
   fmt.Println("ping called")
   // 打印输出 name
   fmt.Println("print persistent flag configFile: ", configFile)
   // 打印输出local flag: dsn
   fmt.Println("(local flag) print ip: ", ip)
   fmt.Println("author is : ",author)
   fmt.Println("viper author: ",viper.Get("author"))
},

启动运行:

$ go run main.go ping --ip 192.168.164.195 --author zsx242030
ping called
print persistent flag configFile:  $HOME/app.conf
(local flag) print ip:  192.168.164.195
author is :  zsx242030
viper author:  zsx242030
# 如果不加--author
go run main.go ping --ip 192.168.164.195
ping called
print persistent flag configFile:  $HOME/app.conf
(local flag) print ip:  192.168.164.195
author is :  zhangsan
viper author:  zhangsan

这样就将 viper 配置和 flag 绑定,如果用户不设置 --author,将从配置中查找。

4.4 arguments 命令行参数设置

cobra 内置的参数验证也是比较多,NoArgs、OnlyValidArgs、MinimumNArgs、MaximumNArgs等等,可以满

足基本使用,如果有自己的特殊要求可以通过解析 arg 来实现。

可以用Command 的 Args 字段指定参数效验规则。

Cobra 也内置了一些规则:

  • NoArgs:如果有任何命令行args参数,将会报错
  • ArbitraryArgs:该命令接受任何参数
  • OnlyValidArgs:如果该命令参数不在 Command 的 ValidArgs 中,将会报错
  • MinimumArgs(int): 如果命令参数数目少于N个,将会报错
  • MaximumArgs(int): 如果命令参数数目多于N个,将会报错
  • ExactArgs(int): 如果命令参数数目不是N个,将会报错
  • RangeArgs(min, max):如果命令参数数目范围不在(min, max),将会报错

内置效验规则的例子:

$ cobra-cli add test
test created at ......\go-cobra
// testCmd represents the test command
var testCmd = &cobra.Command{
	Use:   "test",
	Short: "test short",
	Long: `test short`,
	Args: cobra.MinimumNArgs(5),
	Run: func(cmd *cobra.Command, args []string) {
		fmt.Println("test called")
	},
}

运行:

$ go run main.go test
Error: requires at least 5 arg(s), only received 0
$ go run main.go test aa bb cc dd ee
test called

自定义验证规则的例子:

// testCmd represents the test command
var testCmd = &cobra.Command{
	Use:   "test",
	Short: "test short",
	Long:  `test short`,
	Args: func(cmd *cobra.Command, args []string) error {
		if len(args) < 5 {
			return errors.New("requires at least 5 arg(s)")
		}
		if args[0] != "aa" {
			return errors.New("first must is aa")
		}
		return nil
	},
	Run: func(cmd *cobra.Command, args []string) {
		fmt.Println("test called")
	},
}

运行:

$ go run main.go test aa bb cc dd
Error: requires at least 5 arg(s)
$ go run main.go test ff bb cc dd ee
Error: first must is aa
$ go run main.go test aa bb cc dd ee
test called

4.5 钩子函数PreRun and PostRun Hooks

可以在执行命令之前或之后运行钩子函数。如果子命令未声明自己的 PersistentPreRun

PersistentPostRun函数,则子命令将继承父命令的钩子函数。

函数的执行顺序为:

  • PersistentPreRun
  • PreRun
  • Run
  • PostRun
  • PersistentPostRun

cmd/root.go中添加如下内容:

// rootCmd represents the base command when called without any subcommands
var rootCmd = &cobra.Command{
   Use:   "proj",
   Short: "A brief description of your application",
   Long: `A longer description that spans multiple lines and likely contains
examples 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 files
to quickly create a Cobra application.`,
   // Uncomment the following line if your bare application
   // has an action associated with it:
   // Run: func(cmd *cobra.Command, args []string) { },
   PersistentPreRun: func(cmd *cobra.Command, args []string) {
      fmt.Printf("Inside rootCmd PersistentPreRun with args: %v\n", args)
   },
   PreRun: func(cmd *cobra.Command, args []string) {
      fmt.Printf("Inside rootCmd PreRun with args: %v\n", args)
   },
   Run: func(cmd *cobra.Command, args []string) {
      fmt.Printf("Inside rootCmd Run with args: %v\n", args)
   },
   PostRun: func(cmd *cobra.Command, args []string) {
      fmt.Printf("Inside rootCmd PostRun with args: %v\n", args)
   },
   PersistentPostRun: func(cmd *cobra.Command, args []string) {
      fmt.Printf("Inside rootCmd PersistentPostRun with args: %v\n", args)
   },
}

启动:

$ go run main.go cat arg1 arg2
Inside rootCmd PersistentPreRun with args: [arg1 arg2]
cat called
print persistent flag configFile:  $HOME/app.conf
Inside rootCmd PersistentPostRun with args: [arg1 arg2]

cmd/cat.go中添加如下内容:

// catCmd represents the cat command
var catCmd = &cobra.Command{
	Use:   "cat",
	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("cat called")
		// 打印输出 name
		fmt.Println("print persistent flag configFile: ", configFile)
	},
	PreRun: func(cmd *cobra.Command, args []string) {
		fmt.Printf("Inside subCmd PreRun with args: %v\n", args)
	},
	PostRun: func(cmd *cobra.Command, args []string) {
		fmt.Printf("Inside subCmd PostRun with args: %v\n", args)
	},
}

启动:

$ go run main.go cat arg1 arg2
Inside rootCmd PersistentPreRun with args: [arg1 arg2]
Inside subCmd PreRun with args: [arg1 arg2]
cat called
print persistent flag configFile:  $HOME/app.conf
Inside subCmd PostRun with args: [arg1 arg2]
Inside rootCmd PersistentPostRun with args: [arg1 arg2]

4.6 错误处理函数和钩子函数

与上面的钩子函数功能一样,只不过这里可以返回错误,处理RunE 功能的执行先后顺序如下:

  • PersistentPreRunE
  • PreRunE
  • RunE
  • PostRunE
  • PersistentPostRunE
RunE: func(cmd *cobra.Command, args []string) error {
    fmt.Printf("Inside subCmd Run with args: %v\n", args)
    return nil
},

4.7 为你的命令生成文档

Cobra 可以基于子命令、标志等生成文档。具体的使用方法和生产格式文档请点击下面链接:

https://pkg.go.dev/github.com/spf13/cobra/doc

  • Man page docs
  • Markdown docs
  • Rest docs
  • Yaml docs

这里我们生成 Markdown Docs

package main

import (
	"github.com/spf13/cobra"
	"github.com/spf13/cobra/doc"
	"log"
)

func main() {
	cmd := &cobra.Command{
		Use:   "test",
		Short: "my test program",
	}
	err := doc.GenMarkdownTree(cmd, "./")
	if err != nil {
		log.Fatal(err)
	}
}

生成的内容:

## test

my test program

### Options

​```
  -h, --help   help for test```

###### Auto generated by spf13/cobra on 31-May-2023

你可以设置 cmd.DisableAutoGenTag = true 从而把文档中 Auto generated by spf13/cobra... 等字样删

掉。

4.8 help命令

命令: cobra-cli help,可以清楚显示出对使用 cobra 有用的信息,比如命令提示:

$ cobra-cli help
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.

Usage:
  cobra-cli [command]

Available Commands:
  add         Add a command to a Cobra Application
  completion  Generate the autocompletion script for the specified shell
  help        Help about any command
  init        Initialize a Cobra Application

Flags:
  -a, --author string    author name for copyright attribution (default "YOUR NAME")
      --config string    config file (default is $HOME/.cobra.yaml)
  -h, --help             help for cobra-cli
  -l, --license string   name of license for the project
      --viper            use Viper for configuration

Use "cobra-cli [command] --help" for more information about a command.

你还可以定义自己的 help 命令或模板:

cmd.SetHelpCommand(cmd *Command)
cmd.setHelpCommand(f func(*Command, []string))
cmd.setHelpTemplate(s string)

正常情况下的输出:

go run main.go test -h
test short

Usage:
  proj test [flags]

Flags:
  -h, --help   help for test

Global Flags:
      --author string       Author name for copyright attribution (default "zhangsan")
      --configfile string   config file (default is $HOME/app.conf) (default "$HOME/app.conf")

自己设置:

func init() {
	rootCmd.AddCommand(testCmd)
	testCmd.SetHelpTemplate(`Usage:
  test [flags]
Flags:
  -h, --help   help for test`)
}
$ go run main.go test -h
Usage:
  test [flags]
Flags:
  -h, --help   help for test

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【从球开始渲染小姐姐】DAY1----用blender捏一个小姐姐

Building Blender/Windows - Blender Developer Wikihttps://wiki.blender.org/wiki/Building_Blender/Windows How to build Blender on Windows? - YouTubehttps://www.youtube.com/watch?vb6CtGm4vbng bf-blender - Revision 63388: /trunk/lib/win64_vc15https://svn.b…

DJ4-6 虚拟存储器的基本概念

目录 4.6.1 虚拟存储器的引入 1、常规存储器管理方式的特征 2、内存的扩充方法 4.6.2 局部性原理 4.6.3 虚拟存储器的定义 1、虚拟存储器的基本工作情况 2、虚拟存储器的定义 3、虚拟存储器的实现方法 4.6.4 虚拟存储器的特征 基本分页和基本分段不能解决的问题&a…

snpEFF和bedtools基因注释有何异同?

大家好&#xff0c;我是邓飞&#xff0c;现在写博客越来越繁琐了&#xff0c;每个平台对图片都有自己的规则&#xff0c;不能通用&#xff0c;各种找不到图片&#xff0c;本着充值是我变强的原则&#xff0c;买了Markdown Nice的VIP&#xff08;https://product.mdnice.com/&am…

自然语言处理从入门到应用——自然语言处理(Natural Language Processing,NLP)基础知识

分类目录&#xff1a;《自然语言处理从入门到应用》总目录 自然语言通常指的是人类语言&#xff0c;是人类思维的载体和交流的基本工具&#xff0c;也是人类区别于动物的根本标志&#xff0c;更是人类智能发展的外在体现形式之一。自然语言处理&#xff08;Natural Language Pr…

C Primer Plus第十四章编程练习答案

学完C语言之后&#xff0c;我就去阅读《C Primer Plus》这本经典的C语言书籍&#xff0c;对每一章的编程练习题都做了相关的解答&#xff0c;仅仅代表着我个人的解答思路&#xff0c;如有错误&#xff0c;请各位大佬帮忙点出&#xff01; 由于使用的是命令行参数常用于linux系…

LeetCode:1143.最长公共子序列 1035.不相交的线 53. 最大子序和

1143.最长公共子序列 题目 给定两个字符串 text1 和 text2&#xff0c;返回这两个字符串的最长 公共子序列 的长度。如果不存在 公共子序列 &#xff0c;返回 0 。 一个字符串的 子序列 是指这样一个新的字符串&#xff1a;它是由原字符串在不改变字符的相对顺序的情况下删除…

字节和滴滴划水5年,总结出来的真实经验....

先简单交代一下背景吧&#xff0c;某不知名 985 的本硕&#xff0c;17 年毕业加入字节&#xff0c;之后跳槽到了滴滴&#xff0c;一直从事软件测试的工作。之前没有实习经历&#xff0c;算是5年的工作经验吧。 这5年之间完成了一次晋升&#xff0c;换了一家公司&#xff0c;有…

基础巩固(四)View体系与事件分发

文章目录 Android窗口机制ViewRootWindow、WindowManager、ViewRoot、Activity、DecorView之间的关系ViewView的生命周期Attachment / DetachmentTraversalsState Save / Restoreinvalidate()和requestLayout() View的生命周期与Activity的生命周期的关联Activity创建时如何关联…

[深度学习]yolov7 pytorch模型转onnx,转ncnn模型和mnn模型使用细节

文章目录 前言1.前置1.1 安装必要的库1.2 .pt 权重转ncnn 和mnn所需要的权重 2、编码C项目1.ncnn2.mnn 总结 前言 yolov7 pytorch模型转onnx&#xff0c;转ncnn模型和mnn模型使用细节&#xff0c;记录一下 git仓库&#xff1a; yolov7 https://github.com/WongKinYiu/yolov7 n…

JQL的语法格式

JQL&#xff08;Jira Query Language&#xff09;的语法格式如下&#xff1a; <field> <operator> <value> 其中&#xff0c; 表示 Jira 中的字段&#xff08;例如 project、assignee、status 等&#xff09;&#xff0c; 表示操作符&#xff08;例如 、!、&…

uni-app路由进阶—不同路由跳转配置的使用

uni-app路由进阶—不同路由跳转配置的使用 uni-app路由进阶—不同路由跳转配置的使用 文章目录 uni-app路由进阶—不同路由跳转配置的使用前言一、配置2个一级导航页面&#xff08;tabBar&#xff09;二、路由配置分类总结 前言 UNI-APP学习系列之uni-app路由进阶—不同路由跳…

SQL注入基本原理

1、什么是Sql注入攻击 SQL注入攻击通过构建特殊的输入作为参数传入Web应用程序&#xff0c;而这些输入大都是SQL语法里的一些组合&#xff0c;通过执行SQL语句进而执行攻击者所要的操作&#xff0c;它目前是黑客对数据库进行攻击的最常用手段之一。 本课程将带你从介绍 Web 应用…

ELK日志采集系统搭建

需求背景 现在的系统大多比较复杂&#xff0c;一个服务的背后可能就是一个集群的机器在运行&#xff0c;各种访问日志、应用日志、错误日志量随着访问量和时间会越来越多&#xff0c;运维人员就无法很好的去管理日志&#xff0c;开发人员排查问题&#xff0c;需要到服务器上查…

赛灵思 ZYNQ UltraScale+ MPSoC Petalinux驱动开发:EMIO-GPIO输入驱动

目录 Zynq UltraScale MPSoC Linux下EMIO-GPIO驱动1、MPSOC GPIO简介2、vivado中EMIO配置3、EMIO设备树修改 Zynq UltraScale MPSoC Linux下EMIO-GPIO驱动 声明&#xff1a;本文是学习赛灵思 Zynq UltraScale MPSoC 5EV过程中写的笔记&#xff0c;便于以后复习&#xff0c;参考…

基于Faster R-CNN实现目标检测

目录 1. 作者介绍2. Faster RCNN基本框架3.模型训练及测试3.1 数据集3.2 环境配置3.3 训练参数3.4 训练参数3.5 代码展示3.6 问题及分析 参考&#xff08;可供参考的链接和引用文献&#xff09; 1. 作者介绍 杨金鹏&#xff0c;男&#xff0c;西安工程大学电子信息学院&#x…

Mybatis-puls——入门案例和概述和CURD功能实现

前言 虽然但是&#xff0c;现在MyBatis_puls并不支持springboot3.x版本。 MyBatis_puls就像SpringBoot是为了快速开发Spring程序一样&#xff0c;这个是为了快速开发MyBatis程序。基于SpringBoot使用MP的开发流程 按照下面这个模板造就对了。 SpingBoot——SB整合MB的web项…

Profinet通信协议基础知识

目录 1、Profinet是PI退出的开放式以太网标准: 2、Profinet的参考模式 3、Profinet的应用领域

若依框架快速搭建(一)

若依框架开发 若依框架介绍前期准备相关工具IDEAwebstromNavcatMavenRedis 前后端项目搭建 后端搭建前端搭建源码下载 若依框架介绍 若以管理系统的网址&#xff1a;http://ruoyi.vip/ 代码为开源代码 主要分为四部分&#xff0c;第一个是整体项目&#xff0c;第二个是前后端…

UFS 3 - UFS RPMB

UFS 1-UFS RPMB 1 RPMB介绍2 RPMB Well Known Logical Unit Description3 Requirements3.1 RPMB Resources3.2 Algorithm and Key for MAC Calculation3.3 RPMB Message Components3.4 Request Message Types3.5 Response Message Types3.6 RPMB Operation Result 4 Implementa…

Springboot +spring security,前后端分离时的security处理方案(二)

一.简介 在前后端分离这样的开发模式下&#xff0c;前后端的交互都是通过 JSON 来进行数据传递的&#xff0c;无论登录成功还是失败&#xff0c;都不会有服务端跳转或者客户端跳转之类的操作。 也就是说无论登录成功还是失败&#xff0c;服务端都会返回一段登录成功或失败的 …