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 ,这里不是这种情况......我在这里错过了什么?
您的示例已将错误打印到 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)
或
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
我使用 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 ,这里不是这种情况......我在这里错过了什么?
您的示例已将错误打印到 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)
或
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