如何在 go generate 脚本中等待用户输入?
How to wait for user input in go generate script?
我正在为一个项目开发代码生成器,有时需要等待用户输入才能继续。但是,我发现当 运行 到 go generate
时,读取用户输入的常用方法不会等待用户输入内容后再继续。但是,如果我 运行 以通常的 go run
方式编写脚本,程序会按预期等待用户输入(尽管这对我来说不是一个选项)。
我要问的是:当 运行 到 go generate
时,有没有办法让程序挂起并等待用户输入?
我看过 How can I read from standard input in the console?,虽然相关,但这不是完全相同的问题。
这是一个示例:
main.go
package main
import (
"bufio"
"log"
"os"
)
func main() {
for isFileOk := checkFile(); !isFileOk; {
log.Println("File requires manual update.")
log.Println("Hit [RETURN] when resolved.")
scanner := bufio.NewScanner(os.Stdin)
for scanner.Scan() {
break
}
isFileOk = checkFile()
}
}
func checkFile() bool {
return false
}
generate.go
package main
//go:generate go run main.go
运行 go run main.go
,执行循环的单个迭代,然后等待我点击 return,然后再进行下一次迭代。 运行go generate generate.go
,循环遍历,无需等待。
您可能会注意到,我实际上并不需要从用户那里读取任何数据,相反,我只需要从用户那里获得某种他们已完成文件更新的反馈。如果有另一种方法可以让程序挂起直到用户完成,那也很好。
注意:我也尝试过使用 bufio.Reader
、fmt.Scanln()
和 io.ReadAll(os.Stdin)
而不是 bufio.Scanner
,但得到的结果相同。
go generate generate.go
会fork main.go
usingexec.Command
,go generate
没有为main.go
设置一个stdin
,所以main.go
可以不从 os.Stdin
.
读取键盘输入
另一种方法是直接从 /dev/tty
(unix) 或系统 API(win):
读取键盘事件
package main
import (
"fmt"
"log"
"github.com/eiannone/keyboard"
)
func main() {
if err := keyboard.Open(); err != nil {
panic(err)
}
defer func() {
_ = keyboard.Close()
}()
for isFileOk := checkFile(); !isFileOk; {
log.Println("File requires manual update.")
log.Println("Hit [RETURN] when resolved.")
char, key, err := keyboard.GetKey()
if err != nil {
panic(err)
}
fmt.Println(char, key, err)
if key == keyboard.KeyEsc {
return
}
}
}
func checkFile() bool {
return false
}
我正在为一个项目开发代码生成器,有时需要等待用户输入才能继续。但是,我发现当 运行 到 go generate
时,读取用户输入的常用方法不会等待用户输入内容后再继续。但是,如果我 运行 以通常的 go run
方式编写脚本,程序会按预期等待用户输入(尽管这对我来说不是一个选项)。
我要问的是:当 运行 到 go generate
时,有没有办法让程序挂起并等待用户输入?
我看过 How can I read from standard input in the console?,虽然相关,但这不是完全相同的问题。
这是一个示例:
main.go
package main
import (
"bufio"
"log"
"os"
)
func main() {
for isFileOk := checkFile(); !isFileOk; {
log.Println("File requires manual update.")
log.Println("Hit [RETURN] when resolved.")
scanner := bufio.NewScanner(os.Stdin)
for scanner.Scan() {
break
}
isFileOk = checkFile()
}
}
func checkFile() bool {
return false
}
generate.go
package main
//go:generate go run main.go
运行 go run main.go
,执行循环的单个迭代,然后等待我点击 return,然后再进行下一次迭代。 运行go generate generate.go
,循环遍历,无需等待。
您可能会注意到,我实际上并不需要从用户那里读取任何数据,相反,我只需要从用户那里获得某种他们已完成文件更新的反馈。如果有另一种方法可以让程序挂起直到用户完成,那也很好。
注意:我也尝试过使用 bufio.Reader
、fmt.Scanln()
和 io.ReadAll(os.Stdin)
而不是 bufio.Scanner
,但得到的结果相同。
go generate generate.go
会fork main.go
usingexec.Command
,go generate
没有为main.go
设置一个stdin
,所以main.go
可以不从 os.Stdin
.
另一种方法是直接从 /dev/tty
(unix) 或系统 API(win):
package main
import (
"fmt"
"log"
"github.com/eiannone/keyboard"
)
func main() {
if err := keyboard.Open(); err != nil {
panic(err)
}
defer func() {
_ = keyboard.Close()
}()
for isFileOk := checkFile(); !isFileOk; {
log.Println("File requires manual update.")
log.Println("Hit [RETURN] when resolved.")
char, key, err := keyboard.GetKey()
if err != nil {
panic(err)
}
fmt.Println(char, key, err)
if key == keyboard.KeyEsc {
return
}
}
}
func checkFile() bool {
return false
}