为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

Go
小唯快跑啊 2021-05-12 18:12:12
我有以下程序:package mainimport "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),那么我永远也看不到这个问题,而我的代码却以随机休眠为代价。我在代码中做错什么了吗,或者这是一个错误?如果是错误,是否已解决?
查看完整描述

2 回答

?
慕码人2483693

TA贡献1860条经验 获得超9个赞

转到语句


“ go”语句作为一个独立的并发控制线程或goroutine在同一地址空间内开始执行函数或方法调用。


GoStmt =“ go”表达式。


表达式必须是一个调用。函数值和参数在调用goroutine中照常进行评估,但是与常规调用不同,程序执行不等待被调用函数完成。取而代之的是,该函数开始在新的goroutine中独立执行。当函数终止时,其goroutine也终止。如果函数具有任何返回值,则在函数完成时将其丢弃。


将免费的goroutine转换为函数调用。


package main


import (

    "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)

    }

}


查看完整回答
反对 回复 2021-05-31
  • 2 回答
  • 0 关注
  • 452 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信