Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to debug "exit status 1" error when running exec.Command in Golang

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?

like image 267
laurent Avatar asked Aug 10 '13 07:08

laurent


People also ask

What does exit status 1 mean?

The "Exit Code 1" is simply a "Generic Exit Code" which means the job failed and this can be for any reason.

What is exit status 2 in Golang?

Exit code 2 is supposed to mean 'incorrect arguments' in the Unix tradition. Something like 127 or 255 would be better. -rob. -- You received this message because you are subscribed to the Google Groups "golang-nuts" group.

What is Golang exec?

It is simply a sub-package that allows you to execute external commands using Go.


2 Answers

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.

like image 191
laurent Avatar answered Oct 01 '22 23:10

laurent


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

like image 30
noj Avatar answered Oct 01 '22 23:10

noj