You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在go generate运行的脚本中实现等待用户输入的功能?

问题根因

go generate 执行时默认会将子进程的标准输入(stdin)重定向到空设备,因此所有读取os.Stdin的操作都会立即返回EOF,不会等待用户输入,这就是你现有代码无限循环的原因。


解决方案

方案1:直接读取终端设备实现等待输入(最贴合原需求)

不需要依赖默认的os.Stdin,直接打开当前关联的终端设备读取输入即可,支持跨平台,修改后的代码如下:

package main

import (
    "bufio"
    "log"
    "os"
    "runtime"
)

func main() {
    for isFileOk := checkFile(); !isFileOk; {
        log.Println("File requires manual update.")
        log.Println("Hit [RETURN] when resolved.")

        // 打开当前终端设备,替代被重定向的stdin
        var tty *os.File
        var err error
        if runtime.GOOS == "windows" {
            tty, err = os.Open("CONIN$")
        } else {
            tty, err = os.Open("/dev/tty")
        }
        if err != nil {
            log.Fatalf("打开终端失败: %v", err)
        }
        scanner := bufio.NewScanner(tty)
        // 等待用户输入回车
        scanner.Scan()
        tty.Close()

        isFileOk = checkFile()
    }
}

func checkFile() bool {
    return false
}

修改后直接运行go generate generate.go即可正常等待用户按下回车再继续执行。


方案2:基于标记文件的无输入等待方案(兼容性更强)

如果不想处理终端设备的兼容逻辑,也可以用标记文件实现需求,不需要读取任何输入:

  1. 程序检测到文件需要更新时,提示用户更新完成后在当前目录创建名为update.done的文件
  2. 程序循环检测该文件是否存在,检测到存在后自动删除标记文件,继续执行
    代码示例:
package main

import (
    "log"
    "os"
    "time"
)

const doneFlag = "./update.done"

func main() {
    // 先清理可能残留的标记文件
    os.Remove(doneFlag)
    for isFileOk := checkFile(); !isFileOk; {
        log.Println("File requires manual update.")
        log.Println("Create file [update.done] in current directory when resolved.")
        // 间隔1秒检测标记文件
        time.Sleep(time.Second)
        if _, err := os.Stat(doneFlag); err == nil {
            os.Remove(doneFlag)
            break
        }
    }
}

func checkFile() bool {
    return false
}

该方案完全不依赖标准输入,也适配没有终端的CI/CD场景。


内容的提问来源于stack exchange,提问作者Henry

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.28 17:09:01