douju2014 2016-12-06 14:33
浏览 167

如何通过管道将io.Stdin和io.Stdout传递给exec.Command

I'm trying to read and write to an exec.Command, but I'm struggling with piping.

This first one is a example of the behaviour I want. The go application just proxies stdin, stdout and stderr to the command:

package main

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

func main() {
    cmd := exec.Command("bash", "-i")

    cmd.Stdin = os.Stdin
    cmd.Stdout = os.Stdout
    cmd.Stderr = os.Stderr

    cmd.Run()
    fmt.Println("Done")
}

Running this is like:

pensarando@home: ~/go/src/test$ ./test
pensarando@home: ~/go/src/test$ echo "hello"
hello
pensarando@home: ~/go/src/test$ exit
Done
pensarando@home: ~/go/src/test$ 

But this one does not work at all:

package main

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

func main() {
    cmd := exec.Command("bash", "-i")

    in, _ := cmd.StdinPipe()
    out, _ := cmd.StdoutPipe()
    err, _ := cmd.StderrPipe()

    exit := make(chan struct{})

    done := func() {
        in.Close()
        out.Close()
        err.Close()
        cmd.Wait()
        close(exit)
    }

    var once sync.Once

    go func() {
        io.Copy(os.Stdout, out)
        fmt.Println("done stdout")
        once.Do(done)
    }()

    go func() {
        io.Copy(in, os.Stdin)
        fmt.Println("done stdin")
        once.Do(done)
    }()

    go func() {
        io.Copy(os.Stderr, err)
        fmt.Println("done stderr")
        once.Do(done)
    }()

    cmd.Start()
    <-exit
    fmt.Println("Done")
}

When I run this one from the terminal, the output is for example:

pensarando@home:~/go/src/test$ go build
pensarando@home:~/go/src/test$ ./test
pensarando@home:~/go/src/test$ echo "Hello"

[1]+  Stopped                 ./test
pensarando@home:~/go/src/test$ echo "Hello"
Hello
pensarando@home:~/go/src/test$ fg
./test
done stdin
done stdout
done stderr
Done
pensarando@home:~/go/src/test$

What exactly happens here?

  • 写回答

0条回答 默认 最新

    报告相同问题?

    悬赏问题

    • ¥15 C#算法问题, 不知道怎么处理这个数据的转换
    • ¥15 YoloV5 第三方库的版本对照问题
    • ¥15 请完成下列相关问题!
    • ¥15 drone 推送镜像时候 purge: true 推送完毕后没有删除对应的镜像,手动拷贝到服务器执行结果正确在样才能让指令自动执行成功删除对应镜像,如何解决?
    • ¥15 求daily translation(DT)偏差订正方法的代码
    • ¥15 js调用html页面需要隐藏某个按钮
    • ¥15 ads仿真结果在圆图上是怎么读数的
    • ¥20 Cotex M3的调试和程序执行方式是什么样的?
    • ¥20 java项目连接sqlserver时报ssl相关错误
    • ¥15 一道python难题3