Home > Net >  Why operate normally when bufio.NewWriter get os.Stdin in local
Why operate normally when bufio.NewWriter get os.Stdin in local

Time:10-21

package main

import (
    "bufio"
    "os"
)

func main() {
    bw := bufio.NewWriter(os.Stdin)
    bw2 := bufio.NewWriter(os.Stdout)

    bw.WriteString("Hello, world 1\n")
    bw2.WriteString("Hello, world 2\n")

    bw.Flush()
    bw2.Flush()
}

This code show both string in a local environment. But why does it work differently in different environments?

My local environment OS : macOS 12.6 go : go1.19.2 darwin/amd64 ide : vscode

go in local go in playGruond

CodePudding user response:

The Go Playground
https://go.dev/play/p/PtoDwCZGggd

Scroll all the way down to "About the Playground"

About the Playground

The Go Playground runs the program inside a sandbox.

There are limitations to the programs that can be run in the playground:

The only communication a playground program has to the outside world is by writing to standard output and standard error.

The Go Playground discards writes to standard input.


Locally, os.Stdin is a file.

var (
    Stdin  = NewFile(uintptr(syscall.Stdin), "/dev/stdin")
    Stdout = NewFile(uintptr(syscall.Stdout), "/dev/stdout")
    Stderr = NewFile(uintptr(syscall.Stderr), "/dev/stderr")
)

Stdin, Stdout, and Stderr are open Files pointing to the standard input, standard output, and standard error file descriptors.

CodePudding user response:

The bottom line is : your program does not control what thingy will be used as Stdin and Stdout when it is started.

(also : you should check for errors in your go code)


Try running : echo "" | go run main.go on your machine, or go run main.go < anyfile.

It is a standard setup, when running a command from a terminal, that the shell uses the same file descriptor, which points to a read/write terminal. With that setup, writing to stdin "works".

But you can't really on it (you shouldn't, actually), and it turns out that the playground doesn't start its process that way :

package main

import (
    "fmt"
    "os"
)

func main() {
    _, err := os.Stdin.Write([]byte("Hello\n"))
    if err != nil {
        fmt.Fprintln(os.Stderr, "*** error:", err)
    }
}

// Output:
// *** error: write /dev/stdin: bad file descriptor
//
// Program exited.

https://go.dev/play/p/NmxgOsK2ovp


see also :

Why is it possible to write() to STDIN?

Writing to stdin and reading from stdout (UNIX/LINUX/C Programming)

(found by googling "writing to stdin")

  •  Tags:  
  • go
  • Related