Есть ли способ сохранить стандартный вывод из сценария bash в переменную внутри GO? - PullRequest
0 голосов
/ 19 июня 2020

Я запускаю очень простой bash скрипт, который просто отображает некоторые данные в Go. Я поместил это в оболочку и использовал пакет exe c для выполнения. Это прекрасно работает, выводя на мой терминал, однако я не могу найти способ сохранить это в переменной в Go.

Я новичок в Go, поэтому мои навыки отладки не не удивительно. Тем не менее, я разместил несколько базовых c выходных журналов, чтобы попытаться сузить область, откуда именно мне нужно их получить, но безрезультатно.

Две выполняемые функции bash:

func main(){
    _, result,_ := runBash()
    log.Printf("Result: ", result)
}


func runBash()(bool, string, string){
    cmd := exec.Command("/bin/sh", "-s")
    cmd.Stdin = strings.NewReader(replicateRouter())
    return finishRunning(cmd)
}

func finishRunning(cmd *exec.Cmd) (bool, string, string) {
    log.Printf("Running: ")
    stdout, stderr := bytes.NewBuffer(nil), bytes.NewBuffer(nil)
    cmd.Stdout = os.Stdout
    cmd.Stderr = os.Stderr
    done := make(chan struct{})
    defer close(done)
    go func() {
        for {
            select {
            case <-done:
                return
            case s := <-signals:
                cmd.Process.Signal(s)
            }
        }
    }()
    log.Printf("Flag 1")
    if err := cmd.Run(); err != nil {
        log.Printf("Error running %v", err)
        return false, string(stdout.Bytes()), string(stderr.Bytes())
    }
    log.Printf("Flag 2")
    return true, string(stdout.Bytes()), ""
}

Это функция для имитации проверки моего bash скрипта:

func replicateRouter() string{
    return `echo <HOSTNAME> <IP> <MACADDRESS>`
}

Эхо происходит между флаг 1 и 2, и в любой момент, когда я пытаюсь записать любые значения из cmd / stdout, я получаю пустые строки. В основной функции переменная результата производит: 2020/06/19 18:17:14 Result: %!(EXTRA string=)

Итак, я полагаю, мой первый вопрос: почему результат (который теоретически является строкой (stdout.Bytes ())) не производит эхо? & Во-вторых, где / как я могу сохранить результат в переменной?

Спасибо и не стесняйтесь пинговать меня, если я пропустил какие-либо вопросы и / или мне нужна дополнительная информация

- Изменить : Также забыл упомянуть, что код был в значительной степени вдохновлен этим Kubernetes go скриптом. Если есть какие-то рекомендации / критика в отношении этого, я был бы очень рад услышать / узнать :)

1 Ответ

1 голос

Вопрос 1:

stdout и stderr никогда не назначаются cmd в вашем коде.

попробуйте следующее:

cmd.Stdout = stdout
cmd.Stderr = stderr

или попробуйте эту более простую версию:

  func main() {
      out, err := exec.Command("date").Output()
      if err != nil {
          log.Fatal(err)
      }
      fmt.Printf("The date is %s\n", out)
  }

Наконец, вы можете "прокси" на os.Stdout

package main

import (
    "bytes"
    "fmt"
    "os/exec"
    "io"
    "os"
)


func main() {
    stdout := new(bytes.Buffer)
    stderr := new(bytes.Buffer)
    _, _ = io.Copy(os.Stdout, stdout)
    _, _ = io.Copy(os.Stderr, stderr)

    cmd  := exec.Command("date")
    cmd.Stdout = stdout
    cmd.Stderr = stderr
    cmd.Run()



    output := string(stdout.Bytes())
    fmt.Printf("The date is %s\n", output)
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...