golang标准命令行扩展支持子命令的插件库cmd的使用
golang标准命令行扩展支持子命令的插件库cmd的使用
cmd是一个极简库,可以轻松地使用标准flag
库实现子命令功能。这个库扩展了标准库flag
包,以支持子命令和更多功能,同时保持极简和惯用的API。
功能特性
- 支持子命令
- 自动bash补全
- 标志值定义和检查
- 显式位置参数定义
- 自动生成使用说明文本
使用示例
基本子命令示例
package main
import (
"fmt"
"github.com/posener/cmd"
)
var (
// 定义根命令,包含一个字符串标志
root = cmd.New()
flag0 = root.String("flag0", "", "根命令字符串标志")
// 从根命令定义第一个子命令,包含一个字符串标志
sub1 = root.SubCommand("sub1", "第一个子命令")
flag1 = sub1.String("flag1", "", "sub1字符串标志")
// 从根命令定义第二个子命令,包含一个整型标志
sub2 = root.SubCommand("sub2", "第二个子命令")
flag2 = sub1.Int("flag2", 0, "sub2整型标志")
)
func main() {
// 解析命令行参数
root.ParseArgs("cmd", "sub1", "-flag1", "value")
// 检查用户选择了哪个子命令
switch {
case sub1.Parsed():
fmt.Printf("调用sub1,标志值: %s", *flag1)
case sub2.Parsed():
fmt.Printf("调用sub2,标志值: %d", *flag2)
}
}
高级标志值验证示例
package main
import (
"fmt"
"github.com/posener/cmd"
"github.com/posener/complete/v2/predict"
)
func main() {
var (
root = cmd.New()
// 定义只接受'foo'和'bar'值的标志,并启用值检查
flag1 = root.String("flag1", "", "第一个标志", predict.OptValues("foo", "bar"), predict.OptCheck())
// 定义只接受Go文件路径的标志
file = root.String("file", "", "文件路径", predict.OptPredictor(predict.Files("*.go")), predict.OptCheck())
// 定义位置参数,可选值为'baz'和'buzz'但不强制检查
args = root.Args("[args...]", "位置参数", predict.OptValues("baz", "buzz"))
)
// 解析模拟命令行参数
root.ParseArgs("cmd", "-flag1", "foo", "-file", "cmd.go", "buz", "bazz")
// 输出结果
fmt.Println(*flag1, *file, *args)
}
位置参数处理示例
package main
import (
"fmt"
"github.com/posener/cmd"
)
func main() {
var (
root = cmd.New()
// 定义位置参数变量
args = root.Args("[args...]", "命令行位置参数")
)
// 解析模拟命令行参数
root.ParseArgs("cmd", "v1", "v2", "v3")
// 输出结果
fmt.Println(*args)
}
自定义位置参数处理
package main
import (
"fmt"
"github.com/posener/cmd"
)
func main() {
var (
root = cmd.New()
// 定义变量来保存位置参数
src, dst string
)
// 定义自定义位置参数处理函数
argsFn := cmd.ArgsFn(func(args []string) error {
if len(args) != 2 {
return fmt.Errorf("需要src和dst两个参数,但得到%d个参数", len(args))
}
src, dst = args[0], args[1]
return nil
})
// 注册位置参数处理函数
root.ArgsVar(argsFn, "[src] [dst]", "命令行位置参数")
// 解析模拟命令行参数
root.ParseArgs("cmd", "from.txt", "to.txt")
// 输出结果
fmt.Println(src, dst)
}
整数位置参数处理
package main
import (
"fmt"
"github.com/posener/cmd"
)
func main() {
var (
root = cmd.New()
// 定义整数位置参数变量
args cmd.ArgsInt
)
// 注册位置参数变量
root.ArgsVar(&args, "[int...]", "要求和数字")
// 解析模拟命令行参数
root.ParseArgs("cmd", "10", "20", "30")
// 计算并输出总和
sum := 0
for _, n := range args {
sum += n
}
fmt.Println(sum)
}
固定数量位置参数处理
package main
import (
"fmt"
"github.com/posener/cmd"
)
func main() {
var (
root = cmd.New()
// 定义固定2个位置参数的变量
args = make(cmd.ArgsStr, 2)
)
// 注册位置参数变量
root.ArgsVar(&args, "[src] [dst]", "命令行位置参数")
// 解析模拟命令行参数
root.ParseArgs("cmd", "from.txt", "to.txt")
// 输出结果
fmt.Println(args)
}
这些示例展示了如何使用cmd库创建支持子命令的命令行工具,包括标志定义、位置参数处理和各种验证功能。
更多关于golang标准命令行扩展支持子命令的插件库cmd的使用的实战教程也可以访问 https://www.itying.com/category-94-b0.html
1 回复
更多关于golang标准命令行扩展支持子命令的插件库cmd的使用的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
Golang 标准命令行扩展:子命令插件库 cmd 使用指南
在 Go 语言中,标准库 flag
提供了基本的命令行参数解析功能,但对于复杂的命令行应用(特别是支持子命令的应用)来说可能不够灵活。cmd
并不是 Go 标准库的一部分,但我们可以使用标准库 flag
结合一些模式来实现子命令功能,或者使用第三方库如 cobra
或 urfave/cli
。
使用标准库实现子命令
下面是一个使用标准库实现子命令的示例:
package main
import (
"flag"
"fmt"
"os"
)
func main() {
// 定义顶级命令
addCmd := flag.NewFlagSet("add", flag.ExitOnError)
listCmd := flag.NewFlagSet("list", flag.ExitOnError)
// 检查子命令
if len(os.Args) < 2 {
fmt.Println("expected 'add' or 'list' subcommands")
os.Exit(1)
}
switch os.Args[1] {
case "add":
// 为 add 命令定义标志
addName := addCmd.String("name", "", "Name to add")
addAge := addCmd.Int("age", 0, "Age of the person")
addCmd.Parse(os.Args[2:])
fmt.Printf("Adding %s, age %d\n", *addName, *addAge)
case "list":
// 为 list 命令定义标志
listAll := listCmd.Bool("all", false, "List all items")
listCmd.Parse(os.Args[2:])
if *listAll {
fmt.Println("Listing all items")
} else {
fmt.Println("Listing recent items")
}
default:
fmt.Println("expected 'add' or 'list' subcommands")
os.Exit(1)
}
}
使用第三方库 cobra
cobra
是一个流行的 Go 命令行库,广泛用于 Kubernetes、Docker 等知名项目。
安装 cobra
go get -u github.com/spf13/cobra/cobra
示例代码
package main
import (
"fmt"
"github.com/spf13/cobra"
"os"
)
func main() {
// 根命令
var rootCmd = &cobra.Command{
Use: "myapp",
Short: "My application is a demo for cobra",
Long: `A longer description of my application that spans multiple lines`,
Run: func(cmd *cobra.Command, args []string) {
fmt.Println("Hello from the root command")
},
}
// 添加子命令
var addCmd = &cobra.Command{
Use: "add",
Short: "Add a new item",
Long: `Add a new item to the list`,
Run: func(cmd *cobra.Command, args []string) {
name, _ := cmd.Flags().GetString("name")
age, _ := cmd.Flags().GetInt("age")
fmt.Printf("Adding %s, age %d\n", name, age)
},
}
// 为 add 命令添加标志
addCmd.Flags().StringP("name", "n", "", "Name of the item")
addCmd.Flags().IntP("age", "a", 0, "Age of the person")
addCmd.MarkFlagRequired("name")
// list 子命令
var listCmd = &cobra.Command{
Use: "list",
Short: "List all items",
Run: func(cmd *cobra.Command, args []string) {
all, _ := cmd.Flags().GetBool("all")
if all {
fmt.Println("Listing all items")
} else {
fmt.Println("Listing recent items")
}
},
}
listCmd.Flags().BoolP("all", "a", false, "List all items")
// 将子命令添加到根命令
rootCmd.AddCommand(addCmd, listCmd)
// 执行命令
if err := rootCmd.Execute(); err != nil {
fmt.Println(err)
os.Exit(1)
}
}
使用 urfave/cli 库
urfave/cli
(原 codegangsta/cli
) 是另一个流行的 Go 命令行库。
安装 cli
go get -u github.com/urfave/cli/v2
示例代码
package main
import (
"fmt"
"log"
"os"
"github.com/urfave/cli/v2"
)
func main() {
app := &cli.App{
Name: "myapp",
Usage: "demonstrate subcommands",
Commands: []*cli.Command{
{
Name: "add",
Aliases: []string{"a"},
Usage: "add a new item",
Flags: []cli.Flag{
&cli.StringFlag{
Name: "name",
Aliases: []string{"n"},
Usage: "name of the item",
Required: true,
},
&cli.IntFlag{
Name: "age",
Aliases: []string{"a"},
Usage: "age of the person",
Value: 0,
},
},
Action: func(c *cli.Context) error {
fmt.Printf("Adding %s, age %d\n", c.String("name"), c.Int("age"))
return nil
},
},
{
Name: "list",
Aliases: []string{"l"},
Usage: "list items",
Flags: []cli.Flag{
&cli.BoolFlag{
Name: "all",
Aliases: []string{"a"},
Usage: "list all items",
Value: false,
},
},
Action: func(c *cli.Context) error {
if c.Bool("all") {
fmt.Println("Listing all items")
} else {
fmt.Println("Listing recent items")
}
return nil
},
},
},
}
err := app.Run(os.Args)
if err != nil {
log.Fatal(err)
}
}
总结
- 标准库 flag:适合简单场景,需要手动处理子命令逻辑
- cobra:功能强大,适合复杂命令行应用,支持自动生成帮助文档、bash 补全等
- urfave/cli:API 简洁,适合快速开发中等复杂度的命令行应用
对于大多数项目,推荐使用 cobra
或 urfave/cli
,它们提供了更丰富的功能和更好的开发体验。