cmd := exec.Command("env")
cmd.Stdin = os.Stdin
cmd.Stdout = os.Stdout
This works well regardless env command doesn't relay on reading from stdin
Yet for
cmd := exec.Command("env")
reader, writer := os.Pipe()
go func() {
io.Copy(writer, os.Stdin)
reader.Close()
}()
cmd.Stdin = reader
cmd.Stdout = os.Stdout
It executes env command well but next blocks until whatever input is made (regardless env doesn't need it)
Even such would reproduce the situation
cmd := exec.Command("env")
cmd.Stdin = struct{io.Reader}{os.Stdin}
cmd.Stdout = os.Stdout
But this actually reproduces the Pipe flow under the hood of Cmd implementation it self once the Stdin is not *os.File (see code )
if f, ok := c.Stdin.(*os.File); ok {
return f, nil
}
pr, pw, err := os.Pipe()
if err != nil {
return nil, err
}
...
So wat is the basic difference here as io.Copy says it should behave the very same way
Copy copies from src to dst until either EOF is reached on src or an error occurs
So what is the diff on providing directly os.Stdin to piping it over intermediate Reader. And how to make a Pipe approach behave the same non blocking way
My actual case is even more complex as it pipes the stdin over a net.Conn still I hope the. understanding of described behavior would give me the same clue for the solution.
Thx.