golang如何查看启动的子进程退出码

有时候用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

所以进去看下源码

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 {

其实就是一步一步看源码的过程

添加新评论