go

Obtener código de salida-Ir



(2)

Estoy usando el paquete: os / exec http://golang.org/pkg/os/exec/ para ejecutar un comando en el sistema operativo, pero parece que no encuentro la manera de obtener el código de salida. Puedo leer el resultado aunque

es decir.

package main import( "os/exec" "bytes" "fmt" "log" ) func main() { cmd := exec.Command("somecommand", "parameter") var out bytes.Buffer cmd.Stdout = &out if err := cmd.Run() ; err != nil { //log.Fatal( cmd.ProcessState.Success() ) log.Fatal( err ) } fmt.Printf("%q/n", out.String() ) }


Aquí está mi versión mejorada basada en la respuesta de @ tux21b

utils/cmd.go

package utils import ( "bytes" "log" "os/exec" "syscall" ) const defaultFailedCode = 1 func RunCommand(name string, args ...string) (stdout string, stderr string, exitCode int) { log.Println("run command:", name, args) var outbuf, errbuf bytes.Buffer cmd := exec.Command(name, args...) cmd.Stdout = &outbuf cmd.Stderr = &errbuf err := cmd.Run() stdout = outbuf.String() stderr = errbuf.String() if err != nil { // try to get the exit code if exitError, ok := err.(*exec.ExitError); ok { ws := exitError.Sys().(syscall.WaitStatus) exitCode = ws.ExitStatus() } else { // This will happen (in OSX) if `name` is not available in $PATH, // in this situation, exit code could not be get, and stderr will be // empty string very likely, so we use the default fail code, and format err // to string and set to stderr log.Printf("Could not get exit code for failed program: %v, %v", name, args) exitCode = defaultFailedCode if stderr == "" { stderr = err.Error() } } } else { // success, exitCode should be 0 if go is ok ws := cmd.ProcessState.Sys().(syscall.WaitStatus) exitCode = ws.ExitStatus() } log.Printf("command result, stdout: %v, stderr: %v, exitCode: %v", stdout, stderr, exitCode) return }

Lo he probado en OSX, si no funciona como se espera en otras plataformas, dígamelo para que podamos hacerlo mejor.


Es fácil determinar si el código de salida fue 0 o algo más. En el primer caso, cmd.Wait() devolverá nil (a menos que haya otro error al configurar los pipes).

Lamentablemente, no hay una plataforma independiente para obtener el código de salida en el caso de error. Esa es también la razón por la cual no es parte de la API. El siguiente fragmento funcionará con Linux, pero no lo he probado en otras plataformas:

package main import "os/exec" import "log" import "syscall" func main() { cmd := exec.Command("git", "blub") if err := cmd.Start(); err != nil { log.Fatalf("cmd.Start: %v") } if err := cmd.Wait(); err != nil { if exiterr, ok := err.(*exec.ExitError); ok { // The program has exited with an exit code != 0 // This works on both Unix and Windows. Although package // syscall is generally platform dependent, WaitStatus is // defined for both Unix and Windows and in both cases has // an ExitStatus() method with the same signature. if status, ok := exiterr.Sys().(syscall.WaitStatus); ok { log.Printf("Exit Status: %d", status.ExitStatus()) } } else { log.Fatalf("cmd.Wait: %v", err) } } }

Solo follow the docs api para obtener más información :)