正确地将stdin上的数据传递给命令,并在golang中从该命令的stdout接收数据

我有以下程序:


package main


import "bytes"

import "io"

import "log"

import "os"

import "os/exec"

import "time"


func main() {

    runCatFromStdinWorks(populateStdin("aaa\n"))

    runCatFromStdinWorks(populateStdin("bbb\n"))

}


func populateStdin(str string) func(io.WriteCloser) {

    return func(stdin io.WriteCloser) {

        defer stdin.Close()

        io.Copy(stdin, bytes.NewBufferString(str))

    }

}


func runCatFromStdinWorks(populate_stdin_func func(io.WriteCloser)) {

    cmd := exec.Command("cat")

    stdin, err := cmd.StdinPipe()

    if err != nil {

        log.Panic(err)

    }

    stdout, err := cmd.StdoutPipe()

    if err != nil {

        log.Panic(err)

    }

    err = cmd.Start()

    if err != nil {

        log.Panic(err)

    }

    go populate_stdin_func(stdin)

    go func() {

            // Removing the following lines allow some output

            // to be fetched from cat's stdout sometimes

            time.Sleep(5 * time.Second)

            io.Copy(os.Stdout, stdout)

    }()

    err = cmd.Wait()

    if err != nil {

        log.Panic(err)

    }

}

循环运行时,没有任何结果,如下所示:


$ while true; do go run cat_thingy.go; echo ; done




^C

这个结果是在虚拟机中从 apt 在 Ubuntu 12.04 上安装 golang-go 之后(go 版本 go1)。我无法在Macbook Air(执行版本go1.0.3)上的执行安装中复制。这似乎是某种比赛条件。实际上,如果我放置一个sleep(1 * time.Second),那么我永远也看不到这个问题,而我的代码却以随机休眠为代价。


我在代码中做错什么了吗,或者这是一个错误?如果是错误,是否已解决?


小唯快跑啊
浏览 455回答 2
2回答

慕码人2483693

转到语句“ go”语句作为一个独立的并发控制线程或goroutine在同一地址空间内开始执行函数或方法调用。GoStmt =“ go”表达式。表达式必须是一个调用。函数值和参数在调用goroutine中照常进行评估,但是与常规调用不同,程序执行不等待被调用函数完成。取而代之的是,该函数开始在新的goroutine中独立执行。当函数终止时,其goroutine也终止。如果函数具有任何返回值,则在函数完成时将其丢弃。将免费的goroutine转换为函数调用。package mainimport (    "bytes"    "io"    "log"    "os"    "os/exec")func main() {    runCatFromStdinWorks(populateStdin("aaa\n"))    runCatFromStdinWorks(populateStdin("bbb\n"))}func populateStdin(str string) func(io.WriteCloser) {    return func(stdin io.WriteCloser) {        defer stdin.Close()        io.Copy(stdin, bytes.NewBufferString(str))    }}func runCatFromStdinWorks(populate_stdin_func func(io.WriteCloser)) {    cmd := exec.Command("cat")    stdin, err := cmd.StdinPipe()    if err != nil {        log.Panic(err)    }    stdout, err := cmd.StdoutPipe()    if err != nil {        log.Panic(err)    }    err = cmd.Start()    if err != nil {        log.Panic(err)    }    populate_stdin_func(stdin)    io.Copy(os.Stdout, stdout)    err = cmd.Wait()    if err != nil {        log.Panic(err)    }}
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go