~/Reading Piped Text in Golang

Jul 10, 2019


To read text piped into a Go program, you typically use os.Stdin. This allows you to receive data from another command via the | (pipe) operator. Here is a brief example:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
package main

import (
    "bufio"
    "fmt"
    "os"
)

func main() {
    scanner := bufio.NewScanner(os.Stdin)
    for scanner.Scan() {
        fmt.Println(scanner.Text())
    }
    if err := scanner.Err(); err != nil {
        fmt.Fprintln(os.Stderr, "Error:", err)
    }
}

Save this as main.go and run:

1
echo "hello world" | go run main.go

This prints hello world to stdout. os.Stdin represents the standard input, so data piped from another process is read by scanner.Scan() line by line. For more on pipes and piping, read the Linux pipes documentation.

If you need all input as a single string or binary blob, use io.ReadAll:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
package main

import (
    "fmt"
    "io"
    "os"
)

func main() {
    data, err := io.ReadAll(os.Stdin)
    if err != nil {
        fmt.Fprintln(os.Stderr, "Read error:", err)
        os.Exit(1)
    }
    fmt.Print(string(data))
}

The process is the same regardless of how data enters your program. Just direct the input via the pipe operator and use os.Stdin as shown above.

For more, see the official Go os and io package docs.

Tags: [golang] [stdin] [pipe]