如何在提示输入文本“Enter input”之前检查os.stdin是否可用?

huangapple go评论85阅读模式
英文:

How to check os.stdin is available before prompting for something with text "Enter input"

问题

我需要从os.stdin中获取一些输入。在打印类似"请输入文本"的语句之前,我该如何检查是否可以读取输入。如果stdin不可用,它会在"请输入文本"之后打印"bad file descriptor"。如何避免这种情况?

package main

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

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
}

这是我尝试的内容。当我使用"nohup可执行文件"运行此程序时,它会显示"bad file descriptor"。

英文:

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.

答案1

得分: 3

os.Stdinos包的一个导出变量,它的类型是*os.File

你可以调用File.Stat()来查看它是否可用,并获取关于它的其他信息(例如,它是否被管道传输或其来源是否是终端):

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

让我们看一个不可用的示例。如果我们首先关闭它,例如使用File.Close()方法:

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

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

输出结果(在Go Playground上尝试):

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

还可以查看相关问题:https://stackoverflow.com/questions/22744443/check-if-there-is-something-to-read-on-stdin-in-golang

英文:

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(&quot;Stdin not available:&quot;, err)
} else {
	fmt.Println(&quot;Stdin available.&quot;)
}

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(&quot;Closing:&quot;, os.Stdin.Close())

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

Output (try it on the Go Playground):

Stdin available.
Closing: &lt;nil&gt;
Stdin not available: stat /dev/stdin: Bad file number

Also check related question: https://stackoverflow.com/questions/22744443/check-if-there-is-something-to-read-on-stdin-in-golang

huangapple
  • 本文由 发表于 2017年7月19日 15:07:55
  • 转载请务必保留本文链接:https://go.coder-hub.com/45183253.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定