Golang SIGSEGV только на * второй * вызов - PullRequest
0 голосов
/ 08 ноября 2018

У меня есть метод для быстрого запуска команды оболочки:

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). Я новичок в этом деле, поэтому я не совсем понимаю ошибку разыменования нулевого указателя для начала, а тем более, почему это происходит только при втором вызове.

Ответы [ 2 ]

0 голосов
/ 08 ноября 2018

Это происходит из-за этой строки:

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

Если вы используете CentOS, err := cmd.Run() не вернет никаких ошибок. Тогда err будет nil. Но в строке return вы возвращаете err.Error(). Вы не можете использовать доступ к нулевому указателю. Итак, вы получаете эту ошибку.

0 голосов
/ 08 ноября 2018

Вы всегда возвращаете err.Error(), когда нет ошибки (err == 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 {
...