如何在Go语言中实现CLI命令的同步执行,确保Docker镜像加载完成后再显示退出提示?
如何在Go语言中实现CLI命令的同步执行,确保Docker镜像加载完成后再显示退出提示?
嘿,我来帮你捋清楚这个问题~其实你可能对Go执行外部命令的方式有点小误解:exec.Command.Run()本身就是同步阻塞的,它会一直等到你调用的docker命令完全跑完(不管成功还是失败)才会返回结果。那为什么你的退出提示会提前弹出来呢?大概率是你没处理runCommand的返回错误,导致哪怕docker命令执行出问题(比如路径写错、没权限),程序还是自顾自往下走,直接显示退出提示了。
给你调整一下代码,确保docker镜像加载完成(不管成功失败)之后再显示退出提示:
package main import ( "fmt" "os" "os/exec" "strings" ) func runCommand(name string, args ...string) error { fmt.Printf("Running: %s %s\n", name, strings.Join(args, " ")) cmd := exec.Command(name, args...) cmd.Stdout = os.Stdout cmd.Stderr = os.Stderr return cmd.Run() // 这里会阻塞直到命令执行结束,完全同步 } func main() { // 执行docker load命令,并且捕获错误 err := runCommand("docker", "load", "-i", "<path_to_docker_image>") if err != nil { fmt.Printf("Docker命令执行出错啦: %v\n", err) // 出错了也得让用户看到提示再退对吧 fmt.Println("Press Enter to exit...") fmt.Scanln() return } // 只有命令成功跑完,才会到这里 fmt.Println("Docker镜像加载完成!") fmt.Println("Press Enter to exit...") fmt.Scanln() }
这里几个关键点得说清楚:
cmd.Run()是真·同步:它内部已经帮你做了启动命令+等待结束的操作,所以只要你正常调用它,程序绝对不会跳过docker命令直接走后面的退出提示。- 一定要检查错误:万一镜像路径错了、没装docker或者权限不够,
runCommand会返回错误,这时候给用户一个提示,别让他误以为镜像已经加载好了。 - 代码顺序要注意:把退出提示的代码放在
runCommand执行完成的逻辑后面,不管成功失败都要等命令跑完再显示,这样就完全符合你的需求了。
哦对了,如果你之前觉得Go是异步执行命令,可能是把cmd.Start()和cmd.Run()搞混了——cmd.Start()是异步启动,需要你自己调用cmd.Wait()等它完成;而cmd.Run()已经封装了这俩步骤,是同步执行的。
内容来源于stack exchange
相关产品推荐
相关产品推荐

