有时候用golang启动子进程后,想通过退出码获取程序是否正常退出。
先上结果
package main
import (
"log"
"os/exec"
"syscall"
)
func main() {
cmd := exec.Command("/bin/bash", "-c", "ls -")
if err := cmd.Start(); err != nil {
log.Printf("cmd.Start error: %v", err)
}
var exitCode int
if err := cmd.Wait(); err != nil {
if exitError, ok := err.(*exec.ExitError); ok {
exitCode = exitError.ExitCode()
}
}
log.Printf("exit code %d", exitCode)
}
结果虽然很重要,但是过程也一样不可或缺
一般流程都是
cmd := exec.Command
cmd.Start
cmd.Wait
所以进去看下源码
func (c *Cmd) Wait() error {
if c.Process == nil {
return errors.New("exec: not started")
}
if c.finished {
return errors.New("exec: Wait was already called")
}
c.finished = true
state, err := c.Process.Wait()
if c.waitDone != nil {
close(c.waitDone)
}
c.ProcessState = state
var copyError error
for range c.goroutine {
if err := <-c.errch; err != nil && copyError == nil {
copyError = err
}
}
c.closeDescriptors(c.closeAfterWait)
if err != nil {
return err
} else if !state.Success() {
//不是正常退出返回这个错误
return &ExitError{ProcessState: state}
}
return copyError
}
发现返回这个错误&ExitError{ProcessState: state}
再查ProcessState
发现有这么个方法
// ExitCode returns the exit code of the exited process, or -1
// if the process hasn't exited or was terminated by a signal.
func (p *ProcessState) ExitCode() int {
其实就是一步一步看源码的过程