【问题标题】:How to wait for user input in go generate script?如何在 go generate 脚本中等待用户输入?
【发布时间】:2021-12-11 14:21:36
【问题描述】:

我正在为一个项目开发代码生成器,有时需要等待用户输入才能继续。但是,我发现读取用户输入的常用方法在运行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,循环执行一次迭代,然后等待我点击返回,然后再进行下一次迭代。运行go generate generate.go,循环不断迭代,无需等待。

您可能会注意到,我实际上并不需要从用户那里读取任何数据,相反,我只需要从用户那里获得某种反馈,即他们已完成文件更新。如果有另一种方法让程序挂起直到用户完成,那也很好。


注意:我也尝试过使用 bufio.Readerfmt.Scanln()io.ReadAll(os.Stdin) 而不是 bufio.Scanner,但得到了相同的结果。

【问题讨论】:

  • 为什么不能构建和执行?这显然是正确的方法
  • @Pizzalord 这是一个代码生成库的一部分,它有更多的部分并与其他代码生成器一起使用,所以我需要使用go generate

标签: go user-input code-generation


【解决方案1】:

go generate generate.gofork main.go using exec.Commandgo generate 没有为main.go 设置stdin,所以main.go 无法从os.Stdin 读取键盘输入。

另一种方法是直接从/dev/tty(unix) 或 System 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
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-31
    • 1970-01-01
    • 2023-03-08
    相关资源
    最近更新 更多