GO:使用错误的参数运行cli命令

时间:2018-11-05 16:22:14

标签: go command-line command-line-interface go-cobra

我使用眼镜蛇创建CLI命令工具。 除了错误处理之外,其他一切看起来都很好

如果命令是错误发送(错误的参数或错误的输入),我希望返回 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的错误情况 我想看看返回的是std.err而不是std.out

当我执行mycli provide apps myapp时,一切都会好的

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

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

1 个答案:

答案 0 :(得分:0)

您的样本已经将错误同时打印到stdoutstderr

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

如此运行 ./main provide apps something 2> ./stderr.txt创建一个具有以下内容的文本文件(这是眼镜蛇在没有您干预的情况下写入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

了解眼镜蛇可以使您控制错误打印行为可能会很有用。例如,您可以告诉眼镜蛇命令将哪个流打印到:

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

您还可以防止打印错误:

command.SilenceErrors = true

或防止打印使用情况文字:

command.SilenceUsage = true