go - GO:使用错误的参数运行 cli 命令
问题描述
我使用 cobra 创建 CLI 命令工具。除了错误处理,一切看起来都很好
如果错误发送命令(错误的参数或错误的输入),我想要什么返回std.err而不是std.out
为了简化我创建的演示我的用例的secnario
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 ,这里不是这种情况......我在这里错过了什么?
解决方案
您的示例已经将错误打印到stdout
和stderr
。
默认情况下,cobra
包会将遇到的任何错误打印到stderr
,除非您专门更改它。
因此,运行
会创建一个包含以下内容的文本文件(这是 cobra 在没有您干预的情况下./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)
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
推荐阅读
- chef-infra - 如何摆脱 Let's Encrypt 上的“域验证失败”(ACME 协议)
- arduino - 我对 HTTPClient 库的 POST 请求有 JSON 问题
- ios - 委托和回调不适用于传递模型数据
- php - Magento 2 安装 Windows 管理员损坏的链接
- r - 在并行 foreach 中使用 S4 对象类
- c# - 如何在发送前删除 ViewModel 必需的?
- c++ - 根据 C++ 中的字符串输入将字节数组转换为相应的值
- sql-server - 在 WIN-PAK 4.7 MSSQL 数据库中解码二进制数据
- knex.js - upsert 语句中的列引用 xxx 不明确(候选人:excluded.xxx,table.xxx)
- c# - 如何以编程方式将生成的 resx 文件添加到我的 cproj