英文:
How to debug "exit status 1" error when running exec.Command in Golang
问题
当我运行下面的代码时:
cmd := exec.Command("find", "/", "-maxdepth", "1", "-exec", "wc", "-c", "{}", "\\")
var out bytes.Buffer
cmd.Stdout = &out
err := cmd.Run()
if err != nil {
fmt.Println(err)
return
}
fmt.Println("Result: " + out.String())
我得到了以下错误:
退出状态 1
然而,这并不有助于调试错误的确切原因。
如何获取更详细的信息?
英文:
When I run the code below:
cmd := exec.Command("find", "/", "-maxdepth", "1", "-exec", "wc", "-c", "{}", "\\")
var out bytes.Buffer
cmd.Stdout = &out
err := cmd.Run()
if err != nil {
fmt.Println(err)
return
}
fmt.Println("Result: " + out.String())
I am getting this error:
> exit status 1
However this is not helpful to debug the exact cause of the error.
How to get more detailed information?
答案1
得分: 153
解决方案是使用Command对象的Stderr
属性。可以像这样实现:
cmd := exec.Command("find", "/", "-maxdepth", "1", "-exec", "wc", "-c", "{}", "\\")
var out bytes.Buffer
var stderr bytes.Buffer
cmd.Stdout = &out
cmd.Stderr = &stderr
err := cmd.Run()
if err != nil {
fmt.Println(fmt.Sprint(err) + ": " + stderr.String())
return
}
fmt.Println("Result: " + out.String())
运行上述代码,将清楚地显示问题所在:
exit status 1: find: -exec: no terminating ";" or "+"
编辑:
在上面的代码中,我们期望在出现错误时,消息将被打印到stderr,并且命令将返回非零错误代码。这在大多数情况下是标准的。
然而,正如@snorberhuis在下面提到的,有些命令将错误打印到stdout。其他命令可能会将错误打印到stderr,但返回错误代码为0(此时err
将为nil
)。而且,stderr中的消息并不一定意味着有错误(ffmpeg工具经常这样做)。
因此,你可能需要调整上面的代码以适应你期望的命令。
英文:
The solution is to use the Stderr
property of the Command object. This can be done like this:
cmd := exec.Command("find", "/", "-maxdepth", "1", "-exec", "wc", "-c", "{}", "\\")
var out bytes.Buffer
var stderr bytes.Buffer
cmd.Stdout = &out
cmd.Stderr = &stderr
err := cmd.Run()
if err != nil {
fmt.Println(fmt.Sprint(err) + ": " + stderr.String())
return
}
fmt.Println("Result: " + out.String())
Running the above code, would make it clear what the issue is:
> exit status 1: find: -exec: no terminating ";" or "+"
Edit:
In the code above, we expect that in case of error, the messages will be printed to stderr and the command will return a non-zero error code. This is more or less standard.
However, as mentioned below by @snorberhuis, some commands print the errors to stdout. Other commands might print to stderr but return an error code of 0 (in which case err
will be nil
). And having messages in stderr doesn't necessarily mean there's an error (ffmpeg tools do this a lot).
So basically you might need to tweak the code above to accommodate the commands you expect.
答案2
得分: 59
如Laurent所提到的,您可以覆盖Stderr文件描述符以捕获stderr输出,以获得更好的错误消息。如果只是进行相对简单的操作,我个人更喜欢使用CombinedOutput
方法来执行命令:
cmd := exec.Command("find", "/", "-maxdepth", "1", "-exec", "wc", "-c", "{}", "\\")
output, err := cmd.CombinedOutput()
if err != nil {
fmt.Println(fmt.Sprint(err) + ": " + string(output))
return
}
fmt.Println(string(output))
这是上述示例的play.golang.org链接:http://play.golang.org/p/z8k9zO755P
英文:
As Laurent mentioned, you can override the Stderr file descriptor to capture the stderr output for a better error message. I personally prefer to use the CombinedOutput
method for a command if doing something relatively simple:
cmd := exec.Command("find", "/", "-maxdepth", "1", "-exec", "wc", "-c", "{}", "\\")
output, err := cmd.CombinedOutput()
if err != nil {
fmt.Println(fmt.Sprint(err) + ": " + string(output))
return
}
fmt.Println(string(output))
Here's a play.golang.org link for the above example: http://play.golang.org/p/z8k9zO755P
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论