You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用cobra-cli实现中缀命令(如myapp <arg1> to <arg2>)?

实现中缀命令格式的解决方案

你要的myapp <arg1> to <arg2>这种中缀命令格式完全可以用cobra-cli实现,不需要定制开发,下面提供两种可行方案:

方案一:利用TraverseChildren特性保留子命令结构

cobra默认会在主命令满足参数要求后停止解析子命令,但开启TraverseChildren选项后,会继续遍历并匹配后续的子命令,刚好适配你的场景。具体调整如下:

  1. 修改主命令配置:去掉主命令的Run函数(避免提前执行逻辑终止流程),添加TraverseChildren: true,确保主命令接收第一个参数后继续解析子命令。
  2. 确保子命令被添加到主命令:在init函数中调用rootCmd.AddCommand(toCmd),让cobra能识别"to"子命令。
  3. 在子命令中获取主命令参数:通过cmd.Parent().Args拿到主命令的第一个参数,结合子命令自身的参数完成逻辑。

修改后的完整代码示例:

var (
    Version     string // This will be set from main.go
    verbose     bool
)

var rootCmd = &cobra.Command{
    Use:   "commandlijn <station1>",
    Short: "A brief description of your application",
    Long:  ``,
    Args:  cobra.MinimumNArgs(1),
    TraverseChildren: true, // 关键:允许主命令参数后继续解析子命令
    // 移除原Run函数,主命令仅作为参数入口
}

var toCmd = &cobra.Command{
    Use:   "to <station2>",
    Short: "Finds connections between two stations",
    Long: `The 'to' command allows you to find train connections between two stations.
You need to specify the departure station and the arrival station.`,
    Args: cobra.ExactArgs(1),
    Run: func(cmd *cobra.Command, args []string) {
        stationFrom := cmd.Parent().Args[0] // 从主命令获取出发站
        stationTo := args[0]                // 获取到达站
        fmt.Printf("查询从 %s 到 %s 的线路\n", stationFrom, stationTo)
        // 执行你的业务逻辑
    },
}

func Execute() {
    if err := rootCmd.Execute(); err != nil {
        fmt.Println(err)
        os.Exit(1)
    }
}

func init() {
    // 添加to子命令到主命令
    rootCmd.AddCommand(toCmd)

    // 原有的flag配置保留
    rootCmd.Flags().BoolP("version", "V", false, "Print the version number and exit")
    rootCmd.PersistentFlags().BoolVarP(&verbose, "verbose", "v", false, "Enable verbose output")
    rootCmd.Flags().BoolP("toggle", "t", false, "Help message for toggle")
}

方案二:将"to"作为关键字在主命令中解析

如果不需要保留子命令结构,可以直接在主命令中把"to"当作参数分隔关键字,一次性解析两个参数:

var (
    Version     string
    verbose     bool
)

var rootCmd = &cobra.Command{
    Use:   "commandlijn <station1> to <station2>",
    Short: "A brief description of your application",
    Long:  ``,
    Run: func(cmd *cobra.Command, args []string) {
        // 查找"to"的位置,验证参数格式
        toIdx := -1
        for i, arg := range args {
            if arg == "to" {
                toIdx = i
                break
            }
        }
        if toIdx == -1 || toIdx == 0 || toIdx == len(args)-1 {
            fmt.Println("错误:请使用格式 commandlijn <出发站> to <到达站>")
            os.Exit(1)
        }

        stationFrom := args[0]
        stationTo := args[toIdx+1]
        fmt.Printf("查询从 %s 到 %s 的线路\n", stationFrom, stationTo)
        // 执行你的业务逻辑
    },
}

// Execute和init函数保持原有逻辑,注意不需要to子命令
func Execute() {
    if err := rootCmd.Execute(); err != nil {
        fmt.Println(err)
        os.Exit(1)
    }
}

func init() {
    rootCmd.Flags().BoolP("version", "V", false, "Print the version number and exit")
    rootCmd.PersistentFlags().BoolVarP(&verbose, "verbose", "v", false, "Enable verbose output")
    rootCmd.Flags().BoolP("toggle", "t", false, "Help message for toggle")
}

两种方案对比

  • 方案一保留了cobra的子命令结构,适合后续扩展更多子命令的场景,帮助信息也会自动包含"to"命令的说明。
  • 方案二更简洁,直接适配中缀格式,不需要额外的子命令配置,适合逻辑简单的场景。

内容的提问来源于stack exchange,提问作者Erlich Bachman

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.19 13:22:33