Golang SIGSEGV仅在“第二次”通话中

时间:2018-11-08 19:35:08

标签: go sigsegv

我有一种快速运行shell命令的方法:

func runcmd(c string, arg ...string) (string, string, string) {
    var o bytes.Buffer
    var e bytes.Buffer
    cmd := exec.Command(c, arg...)
    cmd.Stdout = &o
    cmd.Stderr = &e
    err := cmd.Run()
    return o.String(), e.String(), err.Error()
}

在我的主机中有以下代码:

func main() {

ver, _, exitcode := runcmd("rpm", "-q", "--queryformat", "%{VERSION}", "redhat-release")
var dist string
if exitcode != "" {
    ver, _, exitcode = runcmd("rpm", "-q", "--queryformat", "%{VERSION}", "centos-release")
    if exitcode != "" {
        fmt.Println("Unknown OS! Exiting without running!")
        os.Exit(3)
    }
    dist = "CentOS"
} else {
    dist = "Redhat/Redhat derivative"
}

fmt.Printf("System is %s %s.\n", dist, ver)
}

运行此命令将生成SIGSEGV。但是,当我评论第二个对runcmd的调用时,它正常运行(返回Unknown OS! Exiting without running! exit status 3)。我是新手,所以我真的不了解开头的nil指针取消引用错误,更不用说为什么它只会在第二次调用时发生。

2 个答案:

答案 0 :(得分:2)

您总是返回err.Error(),如果没有错误(err == nil),则此操作会失败,并取消nil指针的引用。你应该做

func runcmd(c string, arg ...string) (string, string, error) {
  e bytes.Buffer
  cmd := exec.Command(c, arg...)
  cmd.Stdout = &o
  cmd.Stderr = &e
  err := cmd.Run()
  return o.String(), e.String(), err
}

然后

if exitcode != nil {

答案 1 :(得分:1)

发生这种情况的原因是此行:

return o.String(), e.String(), err.Error()

如果您正在运行CentOS,则err := cmd.Run()将不会返回任何错误。然后err将是nil。但是在return行中,您将返回err.Error()。您不能使用对nil指针的访问。因此,您将收到此错误。