GO: 运行 带有错误参数的 cli 命令

GO: Run cli command with wrong args

我使用 cobra 创建 CLI 命令工具。 除了错误处理,一切看起来都很好

如果错误发送了命令(错误的参数或输入错误),我想要什么 return std.err 而不是 std.out

为了简化场景,我创建了这个来演示我的用例

package main

import (
    "errors"
    "fmt"
    "os"

    "github.com/spf13/cobra"
)

var (
    RootCmd = &cobra.Command{
        Use: "myApp",
        Run: func(cmd *cobra.Command, args []string) {
            fmt.Printf("ROOT verbose = %d, args = %v\n", args)
        },
    }

    provideCmd = &cobra.Command{
        Use: "provide",
        Run: nil,
    }

    appCmd = &cobra.Command{
        Use: "apps",
        RunE: func(cmd *cobra.Command, args []string) error {
            name := args[0]
            if name != "myapp" {
                err := errors.New("app name doesnt exist")
                return err
            }
            return nil
        },
        SilenceUsage:               true,
    }


)

func init() {
    // Add the application command to app command
    provideCmd.AddCommand(appCmd)
    //  add provide command to root command
    RootCmd.AddCommand(provideCmd)
}

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

现在,如果我编译二进制文件并针对二进制文件 运行 exec.Command 一切都按预期工作。但是如果我想测试 mycli provide apps apps1 这样的错误场景 我想看到 returned 在 std.err 而不是 std.out

当我执行mycli provide apps myapp时,一切都应该正常

但是如果我 运行 mycli provide apps myapp2 我想得到 std.err 而不是 std.out ,这里不是这种情况......我在这里错过了什么?

https://play.golang.org/p/B00z4eZ7Sj-

您的示例已将错误打印到 stdoutstderr

默认情况下,cobra 包将它遇到的任何错误打印到 stderr,除非您特别更改它。

所以运行 ./main provide apps something 2> ./stderr.txt 创建一个包含以下内容的文本文件(这是 cobra 在没有您干预的情况下写入 stderr 的内容):

Error: app name doesnt exist

和 运行 ./main provide apps something > ./stdout.txt - 创建一个包含以下内容的文本文件(您自己使用 fmt.Println(err) 打印出来的内容,代码中倒数第二行):

app name doesnt exist

这意味着 默认行为将错误打印到 stdoutstderr.

正如 Devin 所建议的那样,将最后一行更改为 os.Stderr.WriteString(err)fmt.Fprintln(os.Stderr, err)(我会使用的那个)将使您的项目仅将所有内容打印到stderr,这意味着打印错误两次:

Error: app name doesnt exist
app name doesnt exist

了解 cobra 允许您对错误打印行为进行一些控制可能会很有用。例如,您可以告诉 cobra 命令要打印到哪个流:

command.SetOutput(os.Stdout)     // Defaults to os.Stderr

您还可以防止打印错误:

command.SilenceErrors = true

或阻止打印使用文本:

command.SilenceUsage = true