我使用眼镜蛇创建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,这里不是这种情况……我在这里想念什么?
答案 0 :(得分:0)
您的样本已经将错误同时打印到stdout
和stderr
。
默认情况下,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
这意味着默认行为会将错误同时输出到stdout
和stderr
。
如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