Join GitHub today
GitHub is home to over 28 million developers working together to host and review code, manage projects, and build software together.Sign up
proposal: os: Stdin, Stdout and Stderr should be interfaces #13473
The three variables os.Stdin, os.Stdout, and os.Stderr are all *Files, for historical reasons (they predate the io.Writer interface definition).
They should be of type io.Reader and io.Writer, respectively. This would make it easier to do interesting things with special input or output processors. For instance, one could say
os.Stdout = bufio.NewWriter(os.Stdout)
and all output, including from log.Printf and fmt.Printf, would be buffered. Much more imaginative things would also be possible.
Also, *File is the root of a large dependency tree that simple programs would be able to avoid.
Can't change it now, but we could in Go 2.
It's not unheard-of to legitimately close stdio streams ("I'm done with you"). Would it be worth making these io.ReadCloser and io.WriteCloser, respectively (if we had a convenient writer equivalent to io.NopCloser)?
An aside: since stdio streams are just the first 3 file descriptors (and are technically files), there's nothing to prevent your process from receiving a seekable regular file as stdin, or a file opened in rw mode for stdout, etc. This is a fairly common occurrence in practice (redirecting input from a file), but it's rare for applications to notice or care that, e.g. stdin might be able to do more than read bytes. However, the functionality needed to handle these very rare cases could be regained with a call to os.NewFile, passing in 0, 1, or 2 as the fd.
An example of what I mean by the aside:
If we compile this as stdin-stat, we can run:
(above results correspond to darwin 14.5.0)
I think we can support interfaced Stdin, Stdout and Stderr in go1.x
and redirect panic to StdoutV2 and redirect fmt.Println to StderrV2,etc..
I am writing a ios app with PacketTunnelExtension with golang which can see NSLog, but can not see the stdout and stderr .I can only rediect stdout and stderr into a temp file ,and read the content with next startup.It will be good to have a callback to rediect the panic content into NSLog.
I agree. We have never added version numbers to an API and in fact, there is a discussion on golang-dev about an interface that looked like versioned when it is actually not, and the end result is that the interface is renamed so that it doesn't have trailing numbers in its name. (search for Import2 and ImportFrom on golang-dev, or see https://golang.org/cl/18630)
referenced this issue
Sep 23, 2016
What is the current thinking on this?
I currently have to set up an os.Pipe to be able to override Stdout (and StdErr) - our use case is that we need to insert a CR before each LF when the
changed the title from
os: Stdin, Stdout and Stderr should be interfaces
proposal: os: Stdin, Stdout and Stderr should be interfaces
Jun 17, 2017
It might be possible to do this almost cleanly without breaking anything. The variables
Then one could add functions to package
For programs that only use
The main difference between this and perfection is that one can't do
but must instead call a function. That might be a viable compromise.
Another approach would be to provide
But I might be missing something.
Remember that this is for Go 2, so slavish compatibility might be set aside for the transition.
Packages that attempt to change the behavior of
If we want to make these outputs more configurable, we should add a proper API for configuring them rather than encouraging users to monkey-patch through global variables.
I've been thinking about this some more.
There may be a role for reassignable default inputs and outputs, but the
If we instead mean “an arbitrary default
If we mean “the destination of