go - 为已执行的进程创建等待/忙碌指示器

标签 go command-line command-line-interface

我有像这样执行子进程的程序

cmd := exec.Command("npm", "install")
log.Printf("Running command and waiting for it to finish...")
err := cmd.Run()
log.Printf("Command finished with error: %v", err)

虽然此命令正在运行,但它会下载并安装 npm 包,这需要 10 到 40 秒之间的一些时间,并且用户在看到标准输出之前不知道发生了什么(10-40 秒取决于网络),有一些东西我可以使用 which 将某些内容打印到 cli 以使其更清楚发生了什么,一些繁忙的指示器(任何类型)直到标准输出打印到 cli ?

最佳答案

你可以使用另一个 goroutine 周期性地打印一些东西(比如一个点),比如每秒。命令完成后,向该 goroutine 发出终止信号。

像这样:

func indicator(shutdownCh <-chan struct{}) {
    ticker := time.NewTicker(time.Second)
    defer ticker.Stop()
    for {
        select {
        case <-ticker.C:
            fmt.Print(".")
        case <-shutdownCh:
            return
        }
    }
}

func main() {
    cmd := exec.Command("npm", "install")
    log.Printf("Running command and waiting for it to finish...")

    // Start indicator:
    shutdownCh := make(chan struct{})
    go indicator(shutdownCh)

    err := cmd.Run()

    close(shutdownCh) // Signal indicator() to terminate

    fmt.Println()
    log.Printf("Command finished with error: %v", err)
}

如果你想在每 5 个点后开始一个新行,可以这样做:

func indicator(shutdownCh <-chan struct{}) {
    ticker := time.NewTicker(time.Second)
    defer ticker.Stop()
    for i := 0; ; {
        select {
        case <-ticker.C:
            fmt.Print(".")
            if i++; i%5 == 0 {
                fmt.Println()
            }
        case <-shutdownCh:
            return
        }
    }
}

关于go - 为已执行的进程创建等待/忙碌指示器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50467037/

相关文章:

java - 从java程序运行linux命令txl

java - 使用 Java 在 Windows 上通过外部应用程序传输数据

types - 如何将 []string 转换为 []namedstring

go - 如何在 Go 中查找字符串的变量字段值?

go - 在 Go 中使用 defer

curl - 为什么cURL请求在ZSH中的每个请求都返回百分号(%)?

windows - 如何获取Maven项目版本到Windows命令行或批处理文件?

java - 我可以在没有 - 标志的情况下使用 Commons CLI 命令行吗?

python - 如何使用 cli 或 boto3 列出 SQS 队列订阅了哪些 SNS 主题?

go - 将结构或指向结构的指针添加到 slice