我使用 cobra 创建 CLI 命令工具。除了错误处理,一切看起来都很好我想要的是如果错误发送了命令(错误的参数或错误的输入)返回std.err而不是std.out为了简化 secnario 我创建了这个来演示我的用例package mainimport ( "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 回答
慕妹3242003
TA贡献1824条经验 获得超6个赞
您的示例已经将错误打印到stdout
和stderr
。
默认情况下,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
这意味着默认行为会向stdout
和stderr
打印错误。
正如 Devin 所建议的那样,将最后一行更改为os.Stderr.WriteString(err)
or fmt.Fprintln(os.Stderr, err)
(我会使用的那一行)将使您的项目将 所有内容打印到stderr
only,这意味着打印错误两次:
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
- 1 回答
- 0 关注
- 69 浏览
添加回答
举报
0/150
提交
取消