1

I have to promt for some input from os.stdin.How can I check this is available for reading before printing statements like "Enter your text" and then read from input.If stdin is not available it is printing bad file descriptor after "Enter your text". how to avoid this?

package main
import (
    "bufio"
    "os"
    "io"
    "fmt"
)
func main(){
consSource := NewConsoleAccessTokenSource("www.google.co.in", os.Stdin)
fmt.Print("Token: ")
    consSource.scanner.Scan()
    err := consSource.scanner.Err()
    if err != nil {
        fmt.Print(err)
    }
    fmt.Print(consSource.scanner.Text())
}
func NewConsoleAccessTokenSource(websiteUrl string, reader io.Reader) *ConsoleAccessTokenSource {
    s := &ConsoleAccessTokenSource{}
    s.WebsiteUrl = websiteUrl
    s.scanner = bufio.NewScanner(reader)
    return s
}
type ConsoleAccessTokenSource struct {
    WebsiteUrl string

    scanner *bufio.Scanner
}

This is what I am trying to do .when I run this program using "nohup executable" it is giving bad file descriptor.

Suresh Chatti
  • 125
  • 2
  • 8

1 Answers1

3

os.Stdin is an exported variable of the os package, it is of type *os.File.

You may call File.Stat() on it to see if it's available and also to get additional info about it (e.g. if it is being piped or its source is a terminal):

if _, err := os.Stdin.Stat(); err != nil {
    fmt.Println("Stdin not available:", err)
} else {
    fmt.Println("Stdin available.")
}

Let's see an example when it's not available. It won't be if we close it first e.g. with the File.Close() method:

fmt.Println("Closing:", os.Stdin.Close())

if _, err := os.Stdin.Stat(); err != nil {
    fmt.Println("Stdin not available:", err)
} else {
    fmt.Println("Stdin available.")
}

Output (try it on the Go Playground):

Stdin available.
Closing: <nil>
Stdin not available: stat /dev/stdin: Bad file number

Also check related question: Check if there is something to read on STDIN in Golang

icza
  • 389,944
  • 63
  • 907
  • 827
  • but if I use nohup for executing program it is still printing stdin available and when I try to read it is printing bad file descriptor – Suresh Chatti Jul 19 '17 at 10:18
  • @SureshChatti How are you trying to read from it? It doesn't print error for me. Please provide a [mcve]. – icza Jul 19 '17 at 11:23
  • @SureshChatti: This works, but you of course can't execute the check before you close the file descriptors. Please show a [mcve] if you still are having trouble getting this to work. – JimB Jul 19 '17 at 15:31
  • When we run the executable with `nohup yourgoexec` command, it still says that the stdin is available, but still the scanning from stdin will give bad file descriptor. So how to identify if `stdin` is not a bad file descriptor without trying to read it first? To reproduce it please execute your code with nohup command in linux. – pinkpanther Aug 12 '17 at 09:50
  • One more thing to note is, it seems like when we execute with nohup command, stdin is being piped with "/dev/null" which might be causing the bad file descriptor at the end, but in any case we should be able to dect it somehow. – pinkpanther Aug 12 '17 at 09:55