Recently run into this when developing my helper package.
Base on example code here: https://go-review.googlesource.com/c/go/+/213337/1/src/os/exec/example_test.go
func ExampleExitError() {
cmd := exec.Command("sleep", "-u")
err := cmd.Run()
var exerr *exec.ExitError
if errors.As(err, &exerr) {
fmt.Printf("the command exited unsuccessfully: %d\n", exerr.ExitCode())
}
The Exit Code
I end up doing the following for my own exec cmd wrapper:
// Return exit code
func (self *MyCmd) ExitCode() int {
var exitErr *exec.ExitError
if errors.As(self.Err, &exitErr) {
return exitErr.ExitCode()
}
// No error
return 0
}
self.Err
is the return value from a exec.Command.Run()
. Complete listing is here: https://github.com/J-Siu/go-helper/blob/master/myCmd.go
Text Error Message
While @colm.anseo answer take consideration of os.patherror
, it doesn't give an error code(int), and IMHO should be handled separately. Instead text error message can be extract from execCmd.Stderr
like follow:
func (self *MyCmd) Run() error {
execCmd := exec.Command(self.CmdName, *self.ArgsP...)
execCmd.Stdout = &self.Stdout
execCmd.Stderr = &self.Stderr
execCmd.Dir = self.WorkDir
self.CmdLn = execCmd.String()
self.Err = execCmd.Run()
self.Ran = true
ReportDebug(&self, "myCmd:", false, false)
ReportDebug(self.Stderr.String(), "myCmd:Stderr", false, false)
ReportDebug(self.Stdout.String(), "myCmd:Stdout", false, false)
return self.Err
}
self.Stderr
is a bytes.Buffer
and pass into execCmd
before Run()
. After execCmd.Run()
, text err can be extracted with self.Stderr.String()
.