我执行子程序的程序,如
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秒的时间,用户不知道发生什么事情,直到他看到stdout(10-40秒取决于网络),有什么东西我可以使用哪些东西打印到cli,以便更清楚地发生某些事情,一些繁忙的指示符(任何类型),直到stdout被打印到cli?
答案 0 :(得分:4)
您可以使用另一个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
}
}
}
答案 1 :(得分:1)
另一种方法是转变icza的答案。由于npm命令是一个长时间运行的执行,因此最好使用goroutine而不是自动收报机(或两者都作为goroutine),但这是一个偏好的问题。
像这样:
func npmInstall(done chan struct{}) {
cmd := exec.Command("npm", "install")
log.Printf("Running command and waiting for it to finish...")
err := cmd.Run()
if err != nil {
log.Printf("\nCommand finished with error: %v", err)
}
close(done)
}
func main() {
done := make(chan struct{})
go npmInstall(done)
ticker := time.NewTicker(3 * time.Second)
defer ticker.Stop()
for {
select {
case <-ticker.C:
fmt.Print(".")
case <-done:
fmt.Println()
return
}
}
}