简体   繁体   English

golang os / exec:分部分从stdout获取数据

[英]golang os/exec: get data from stdout in parts

I want to run an external application from my go code using os/exec . 我想使用os/exec从go代码运行外部应用程序。 The application my_external_script.sh outputs data to stdout in two parts: the first part is quite fast (it writes "A" to stdout after three seconds) and the second part ("B) is being written only after 10 seconds. 应用程序my_external_script.sh数据分为两部分输出到stdout :第一部分非常快(三秒钟后将“ A”写入stdout),第二部分(“ B”)仅在10秒后才被写入。

For example: 例如:

./my_external_script.sh
.....
.....
A (3 seconds elapsed)
.....
.....
.....
.....
.....
.....
B (10 seconds elapsed)
(program exits with 0 status code)

I'm currently executing this like so from my go code: 我目前正在执行这样的代码:

func execMyExternalCmd() (*string, error) {
    cmd := exec.Command("my_external_script.sh")
    var out bytes.Buffer
    cmd.Stdout = &out
    err := cmd.Run()
    if err != nil {
        return nil, err
    }
    var res = out.String()
    return &res, nil
}

The problem is, execMyExternalCmd will only return after 10 seconds, where both "A" and "B" have been written and the program exited. 问题是, execMyExternalCmd只会在10秒钟后返回, execMyExternalCmd已写入“ A”和“ B”并退出了程序。 I would like to use "A" as soon as it's available on the stdout (but also use "B" later on when it's available). 我想在stdout上尽快使用“ A”(但以后也要使用“ B”)。 How can I achieve this? 我该如何实现?

package main

import (
    "bufio"
    "log"
    "os/exec"
)

func main() {
    cmd := exec.Command("sh", "-c", "echo 1;sleep 10;echo 2;")

    outPipe, _ := cmd.StdoutPipe()
    scanner := bufio.NewScanner(outPipe)

    go func() {
        for scanner.Scan() {
            log.Println(scanner.Text())
        }
    }()

    cmd.Start()
    cmd.Wait()

    log.Println("Done")
}

Output: 输出:

2016/12/04 17:11:09 1
2016/12/04 17:11:19 2
2016/12/04 17:11:19 Done

Use channels to send data from the function instead of return. 使用通道从函数发送数据而不是返回。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM