Cobra - Go 命令行框架
Cobra 是 Go 最流行的命令行框架,被 kubectl、docker、github-cli 等知名项目使用。它提供了丰富的子命令、标志、参数等功能,是开发 CLI 工具的首选。
快速开始
📝 基础命令行
package main
import (
"fmt"
"os"
"github.com/spf13/cobra"
)
var (
name string
verbose bool
)
// root 命令
var rootCmd = &cobra.Command{
Use: "myapp",
Short: "My CLI Application",
Long: `A longer description of my CLI application.`,
Run: func(cmd *cobra.Command, args []string) {
if verbose {
fmt.Println("Verbose mode enabled")
}
fmt.Printf("Hello, %s!\n", name)
},
}
func init() {
// 定义标志
rootCmd.Flags().StringVarP(&name, "name", "n", "World", "Your name")
rootCmd.Flags().BoolVarP(&verbose, "verbose", "v", false, "Verbose output")
}
func main() {
if err := rootCmd.Execute(); err != nil {
fmt.Println(err)
os.Exit(1)
}
}
子命令
📝 添加子命令
package main
import (
"fmt"
"github.com/spf13/cobra"
)
// server 命令
var serverCmd = &cobra.Command{
Use: "server",
Short: "Start the server",
Run: func(cmd *cobra.Command, args []string) {
port, _ := cmd.Flags().GetInt("port")
fmt.Printf("Starting server on port %d...\n", port)
},
}
// server start 子命令
var serverStartCmd = &cobra.Command{
Use: "start",
Short: "Start server",
Run: func(cmd *cobra.Command, args []string) {
fmt.Println("Server started")
},
}
// server stop 子命令
var serverStopCmd = &cobra.Command{
Use: "stop",
Short: "Stop server",
Run: func(cmd *cobra.Command, args []string) {
fmt.Println("Server stopped")
},
}
func init() {
// 添加子命令
rootCmd.AddCommand(serverCmd)
serverCmd.AddCommand(serverStartCmd)
serverCmd.AddCommand(serverStopCmd)
// 添加标志
serverCmd.Flags().IntP("port", "p", 8080, "Server port")
}
// 使用:
// myapp server start --port 9000
// myapp server stop
标志类型
📝 各种标志类型
func init() {
// String 类型
rootCmd.Flags().String("config", "", "Config file")
rootCmd.Flags().StringP("output", "o", "", "Output file")
// Int 类型
rootCmd.Flags().Int("count", 1, "Number of items")
rootCmd.Flags().IntP("port", "p", 8080, "Port number")
// Bool 类型
rootCmd.Flags().Bool("debug", false, "Debug mode")
rootCmd.Flags().BoolP("verbose", "v", false, "Verbose")
// Float 类型
rootCmd.Flags().Float64("timeout", 30.0, "Timeout in seconds")
// String 数组
rootCmd.Flags().StringSlice("tags", []string{}, "Tags")
// Int 数组
rootCmd.Flags().IntSlice("ports", []int{}, "Ports")
// 获取标志值
var config string
rootCmd.Flags().StringVar(&config, "config", "", "Config file")
// 在 Run 中获取
func(cmd *cobra.Command, args []string) {
config, _ := cmd.Flags().GetString("config")
port, _ := cmd.Flags().GetInt("port")
verbose, _ := cmd.Flags().GetBool("verbose")
}
}
参数验证
📝 参数验证器
var echoCmd = &cobra.Command{
Use: "echo [string]",
Short: "Echo the input",
// 参数验证
Args: cobra.ExactArgs(1), // 必须 1 个参数
Run: func(cmd *cobra.Command, args []string) {
fmt.Println("Echo: " + args[0])
},
}
// 其他验证器
var cmds = []*cobra.Command{
{
Use: "no-args",
Args: cobra.NoArgs, // 不能有参数
},
{
Use: "min-args",
Args: cobra.MinimumNArgs(2), // 至少 2 个参数
},
{
Use: "max-args",
Args: cobra.MaximumNArgs(3), // 最多 3 个参数
},
{
Use: "exact-args",
Args: cobra.ExactArgs(2), // 精确 2 个参数
},
{
Use: "range-args",
Args: cobra.RangeArgs(1, 3), // 1 到 3 个参数
},
{
Use: "only-files",
Args: cobra.OnlyValidArgs, // 只能是 ValidArgs 中的值
ValidArgs: []string{"bash", "zsh", "fish"},
},
}
持久标志
📝 持久标志 (子命令共享)
func init() {
// 持久标志:所有子命令都可使用
rootCmd.PersistentFlags().StringP(
"config", "c", "", "Config file path",
)
// 普通标志:仅当前命令可用
rootCmd.Flags().BoolP(
"verbose", "v", false, "Verbose output",
)
}
// 使用:
// myapp --config /etc/app.conf server start -v
// config 对 server 和 start 都可用
// verbose 仅对 server 可用
完整示例
📝 完整 CLI 应用
package main
import (
"fmt"
"os"
"github.com/spf13/cobra"
)
var (
cfgFile string
verbose bool
)
var rootCmd = &cobra.Command{
Use: "todo",
Short: "Todo CLI Application",
Long: `A command line todo list manager.`,
}
// add 命令
var addCmd = &cobra.Command{
Use: "add [task]",
Short: "Add a new task",
Args: cobra.MinimumNArgs(1),
Run: func(cmd *cobra.Command, args []string) {
task := args[0]
fmt.Printf("Added task: %s\n", task)
},
}
// list 命令
var listCmd = &cobra.Command{
Use: "list",
Short: "List all tasks",
Run: func(cmd *cobra.Command, args []string) {
fmt.Println("Listing tasks...")
},
}
// complete 命令
var completeCmd = &cobra.Command{
Use: "complete [task-id]",
Short: "Mark task as complete",
Args: cobra.ExactArgs(1),
Run: func(cmd *cobra.Command, args []string) {
fmt.Printf("Completed task: %s\n", args[0])
},
}
func init() {
// 持久标志
rootCmd.PersistentFlags().StringVarP(
&cfgFile, "config", "c", "", "Config file",
)
rootCmd.PersistentFlags().BoolVarP(
&verbose, "verbose", "v", false, "Verbose output",
)
// 添加子命令
rootCmd.AddCommand(addCmd)
rootCmd.AddCommand(listCmd)
rootCmd.AddCommand(completeCmd)
// add 命令标志
addCmd.Flags().StringP("priority", "p", "medium", "Priority level")
}
func main() {
if err := rootCmd.Execute(); err != nil {
fmt.Println(err)
os.Exit(1)
}
}
最佳实践
✅ Cobra 使用建议
- 命令结构: 使用子命令组织功能
- 持久标志: 全局配置使用 PersistentFlags
- 参数验证: 使用 Args 验证器
- 帮助信息: 提供清晰的 Short/Long 描述
- 错误处理: Execute 返回错误要处理