DEV Community

Cover image for Embrace the Pipe

Embrace the Pipe

trashhalo profile image Stephen Solka ・2 min read

The unix pipe operator is magical.

As long as you write your application to read input from standard-in and write output to standard-out you can compose your cli tool with thousands of other tools.


To read one line at a time I like to use bufio.NewScanner. This uses bufio.ScanLines to split the reader by new lines.

in := bufio.NewScanner(os.Stdin)
// Scan returns false when its out of lines
for in.Scan() {
  // line is a string
  line := in.Text()
  // if you want bytes in.Bytes() exists too
Enter fullscreen mode Exit fullscreen mode

Lets build a tool

As an example here is a tiny command line tool I wrote to read urls for images and display them as ascii art images on the terminal.

Full source

func main() {
    in := bufio.NewScanner(os.Stdin)
    for in.Scan() {
        line := in.Text()
        err := convertLineToArt(line)
        if err != nil

func convertLineToArt(line string) error {
    resp, err := http.Get(line)
    if err != nil {
    defer resp.Body.Close()

    img, _, err := image.Decode(resp.Body)

    convertOptions := convert.DefaultOptions
    convertOptions.FixedWidth = 50
    convertOptions.FixedHeight = 50
    converter := convert.NewImageConverter()
    for _, row := range converter.Image2ASCIIMatrix(img, &convertOptions) {
    return nil
Enter fullscreen mode Exit fullscreen mode

Use Pipe

Now lets combine together a few tools.

curl -A "test" | jq -r '.data.children[] | .data.url'|go run .|less
Enter fullscreen mode Exit fullscreen mode

This is saying:

  1. curl - download the json for reddit posts on cats. The -A "test" because reddit hates curl user agent so we need to change it.
  2. jq -r 'xyz' - extract the urls for the images from the reddit json.
  3. go run - run your command!
  4. less - Put the output in a little viewer that lets you scroll up and down.

Alt Text

Discussion (0)

Editor guide