go语言得到子程序的返回值

go语言调用外部程序,并获取外部程序的返回值。

例子1: 程序返回0

$ cat main.go
package main

import (
    "fmt"
    "os/exec"
)

func main() {
    cmd := exec.Command("test.sh")
    err := cmd.Run()
    if err != nil {
        fmt.Printf("Return error: %s\n", err)
    } else {
        fmt.Printf("Return OK\n")
    }
}

$ cat test.sh
#!/bin/bash

echo "Hello"
exit 0

运行结果

$ go build && ./main
Return OK

例子2:程序返回非零

$ cat test.sh
#!/bin/bash

echo "Hello"
exit 2

运行结果

$ go build && ./main
Return error: exit status 2

这里我们看到com.Run()的返回成功还是失败的区分是子程序返回值是否为零,其实在这个例子中子程序test.sh执行是正确的,返回2是希望的行为,但是com.Run()把它定义为错误,go就这么设计的,那就没有办法了,需要注意一下就行了。

例子3:区分正常的程序返回值,还是异常错误

例如子程序test.sh不存在,或者test.sh不可执行:

$ ./main
Return error: exec: "test.sh": executable file not found in $PATH

或者test.sh 收到异常信号crash了。

$ ./main
Return error: signal: killed

改造后的main.go


package main

import (
    "fmt"
    "syscall"
    "os/exec"
)

func main() {
    cmd := exec.Command("test.sh")
    err := cmd.Run();

    if err != nil {
        if exitErr, ok := err.(*exec.ExitError); ok {
            status := exitErr.Sys().(syscall.WaitStatus)
            switch {
                case status.Exited():
                    fmt.Printf("Return exit error: exit code=%d\n", status.ExitStatus())
                case status.Signaled():
                    fmt.Printf("Return exit error: signal code=%d\n", status.Signal())
            }
        } else {
            fmt.Printf("Return other error: %s\n", err)
        }
    } else {
        fmt.Printf("Return OK\n")
    }
}

场景1: 正常退出0

$ cat test.sh
#!/bin/bash

echo "Hello"
exit 0
$ ./main
Return OK

子程序正常运行结束,并返回0值。

场景2: 正常退出100

$ cat test.sh
#!/bin/bash

echo "Hello"
exit 100
$ ./main
Return exit error: exit code=100

子程序正常运行结束,并返回100值。

场景3:test.sh不存在或者不可执行

$ chmod -x test.sh
$ ./main
Return other error: exec: "test.sh": executable file not found in $PATH

子程序无法运行,我们得到的是其他类型的错误,而不是exec.ExitError类型错误。

场景4: test.sh 运行中被kill -9

$ cat test.sh
#!/bin/bash

echo "Hello"

sleep 100

exit 100
$ ./main
Return exit error: signal code=9

返回exec.ExitError类型错误,我们拿到signal值为9

注意在另一个Terminal中kill掉test.sh
$ kill -9 PID_OF_test.sh

你可能感兴趣的:(go语言得到子程序的返回值)