go - 当标准输入为管道时如何从设备读取

标签 go pipe stdin

所以我有一个从 STDIN 读取的 Go 程序,如下所示。我希望从键盘或设备输入用户名和密码,但可以使用管道传递字符串 slice 。如果我运行如下命令:

echo "Hello World" | go run main.go

os.Stdin 将被设置为从管道读取而不是键盘。有没有一种方法可以更改 os.Stdin FileMode,使其从设备读取,即用户名和密码的键盘?

我尝试使用 os.Stdin.Chmod(FileMode) 但收到此错误:

chmod /dev/stdin: invalid argument

func main() {
  var n = []string{}
  scanner := bufio.NewScanner(os.Stdin)
  fmt.Println("Please type anything with Newline Separated, empty line signals termination")
  for scanner.Scan() {
    h := scanner.Text()
    if h == "" {
      break
    }
    n = append(n, h)
  }
  if err := scanner.Err(); err != nil {
    fmt.Printf("Error in reading from STDIN: %v\n", err)
  }

  reader := bufio.NewReader(os.Stdin)
    os.Stdout.WriteString("Username: ")
    username, err := reader.ReadString('\n')
    if err != nil {
        fmt.Printf("Unable to read username: %v\n", err)
  }
  username = strings.TrimSpace(username)

  os.Stdout.WriteString("Password: ")
  bytePassword, _ := terminal.ReadPassword(int(os.Stdin.Fd()))

  password := string(bytePassword)
  os.Stdout.WriteString("\n")
}

最佳答案

可能 scanf可以帮助,检查这个例子:

https://play.golang.org/p/tteQNl0trJp

package main

import (
    "fmt"
)

func main() {
    fmt.Println("Enter your name")

    var name string
    fmt.Scanf("%s", &name)
    fmt.Printf("name = %s\n", name)
}

一些更详细的内容来检查是否有可以从 stdin 读取的内容,如果没有提示用户:

https://play.golang.org/p/7qeAQ5UNhdQ

package main

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

func main() {
    // check if there is somethinig to read on STDIN
    stat, _ := os.Stdin.Stat()
    if (stat.Mode() & os.ModeCharDevice) == 0 {
        var stdin []byte
        scanner := bufio.NewScanner(os.Stdin)
        for scanner.Scan() {
            stdin = append(stdin, scanner.Bytes()...)
        }
        if err := scanner.Err(); err != nil {
            log.Fatal(err)
        }
        fmt.Printf("stdin = %s\n", stdin)
    } else {
        fmt.Println("Enter your name")

        var name string
        fmt.Scanf("%s", &name)
        fmt.Printf("name = %s\n", name)
    }
}

关于go - 当标准输入为管道时如何从设备读取,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49704456/

相关文章:

arrays - 调用 append 后 slice 的行为是否定义明确?

regex - 开始,尝试循环日期正则表达式结果

c++ - 如何将程序变成守护程序

bash - 使用管道命令忽略 Bash 脚本中的 HUP 信号

c - 如何从标准输入正确写入非ascii文件

c - 在 C (Linux) 中重定向标准输入和输出

使用 shell_exec(bash read) 的 PHP 在 tty 上工作,但在输入通过管道传输且没有换行符时不起作用

go - 如何获取标准 golang 包的版本并更新它?

go - go lang 中 map 的序列化和反序列化问题

c - dup2 错误的文件描述符错误