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?
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.
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