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

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 想起从前的 快乐的日子 想到现在的你 并不快乐 你的快乐 不再是我的 我多希望 你能一直 一直快乐 ​​​​ 20...
    更向远行阅读 223评论 0 0
  • 生活往往被现实打败,而那些你觉的变了的人,他们其实并没有改变,而是他们适应了现在的生活环境
    静静观望阅读 106评论 0 0
  • 冬天才刚刚走远,我和妹妹就迫不及待的来到了这个世界。妹妹自幼体弱,不好照顾,所以得以留在妈妈身边,我被好心的姥姥姥...
    六便士__阅读 474评论 2 6