zyxyeg
Last Updated: February 25, 2016
·
7.911K
· txgruppi
10464074 938292239583056 7575720943166745998 n

golang: having fun with os.Stdin and shell pipes

How can we know when our app have a piped stdin or not?

os.Pipe is a os.File so we can use File.Stat() which return a os.FileInfo and we can use FileInfo.Size() to see if there is any data available to read.

package main

import  (
  "os"
  "fmt"
)

func main() {
  fi, err := os.Stdin.Stat()
  if err != nil {
    panic(err)
  }
  if fi.Size() > 0 {
    fmt.Println("there is something to read")
  } else {
    fmt.Println("stdin is empty")
  }
}

This will work with $ date | go run main.go but not $ curl http://www.google.com/ | go run main.go.

Since curl need some time to send data we will always get 0 (zero) for FileInfo.Size().

To make it work we have to use FileInfo.Mode().

package main

import (
  "os"
  "fmt"
)

func main() {
  fi, err := os.Stdin.Stat()
  if err != nil {
    panic(err)
  }
  fmt.Printf("%v\n", fi.Mode())
}
$ go run main.go
Dcrw--w----
$ date | go run main.go
prw-rw----

What is this?

File.Mode() return a FileMode flag.

You can see what is each letter here FileMode.

The flag we are looking for is os.ModeNamedPipe. When this flag is on it means that we have a pipe.

package main

import (
  "os"
  "fmt"
)

func main() {
  fi, err := os.Stdin.Stat()
  if err != nil {
    panic(err)
  }
  if fi.Mode() & os.ModeNamedPipe == 0 {
    fmt.Println("no pipe :(")
  } else {
    fmt.Println("hi pipe!")
  }
}

This way we can know when our command is receiving stdout from another process.

If you have any other ideia comment it.

You can comment about my english mistakes too so i can learn.

Thank you.

Say Thanks
Respond

3 Responses
Add your response

12114
D3b2094f1b3386e660bb737e797f5dcc

I'm still learning golang myself. Thanks for sharing - I learned something new today!

over 1 year ago ·
12116
10464074 938292239583056 7575720943166745998 n

I'm learning golang too. Do you know http://exercism.io/ ? It's a great place to practice. Thank you.

over 1 year ago ·
18210
None

Thank you. This article really helped me.

over 1 year ago ·
Filed Under