【问题标题】:Can not run bash `read` command from Golang [duplicate]无法从 Golang 运行 bash `read` 命令 [重复]
【发布时间】:2016-01-20 16:10:53
【问题描述】:

我尝试使用基本 bash 命令read 从键盘捕获单个字符。但是我尝试了几种方法似乎很难得到输出。

示例代码:

fmt.Println(exec.Command("read", "-t", "5", "-n", "1").Output())

其含义是“等待 5 秒从键盘获取 1 个输入字符”。从上面的代码中,我希望看到我的输入字符连同它的错误一起打印出来,但我得到的是

输出:

[] exit status 1

此输出仅在不到 1 秒的时间内立即打印,这与代表等待 5 秒的 read 命令的 "-t", "5" 参数冲突。我尝试在 1 秒内输入一些字符,但似乎根本不起作用。

顺便说一句,如果试试这个

fmt.Println(exec.Command("echo", "\"Hi!\"").Output())

输出:

[34 104 105 34 10] <nil>

这里似乎可以使用简单的echo

【问题讨论】:

  • Read 是一个 bash 命令,而不是像 echo 一样的 PATH 中的可执行文件。也许在 bash 中调用 read 可能会起作用。我建议找到一个仅限 Go 的解决方案。
  • @Volker 我只想捕获spacebar 仅此而已。您对简单的仅限解决方案有什么建议吗?

标签: go exec stdin


【解决方案1】:

您没有为命令提供标准输入,因此它无法读取任何内容并立即退出。

如果你想将它与调用程序连接到相同的标准输入,你可以使用:

cmd := exec.Command("read", "-t", "5", "-n", "1")
cmd.Stdin = os.Stdin
out, err := cmd.CombinedOutput()

fmt.Println("error:", err)
fmt.Printf("output: %q\n", out)

然而这不会输出任何东西,因为/usr/bin/read 脚本不会打印任何东西。您可能希望在 shell 的上下文中调用内置的 shell read。这将打印读取的字符:

cmd := exec.Command("bash", "-c", "read -t 5 -n 1 C && echo -n $C")
cmd.Stdin = os.Stdin

但最后,您可能应该直接从 go 中的 stdin 读取。

【讨论】:

  • 感谢您的回答@JimB。我试过你的代码,听起来不错,但每次输入时我都会从out 得到“”。
  • @terces907:那是因为read 没有打印任何输出。你想做什么?
  • 我只想得到一个给定的输入字符。
  • @terces907:我添加了更多信息。为什么不直接在 Go 中做呢?
  • @terces907:bash 将read 的tty 置于原始模式。见*.com/questions/15159118/…*.com/questions/14094190/…