我使用以下代码,即“ npm install”的execute命令,现在在调试时,我看到该命令大约需要10..15秒的时间来执行(取决于我拥有多少模块)。我想要的是该命令将在后台执行,并且程序将继续。
cmd := exec.Command(name ,args...)
cmd.Dir = entryPath
在调试中,我看到要移至下一行tass大约10..15秒...
我有两个问题:
npm install
完成后,我需要做其他事情。通常,您需要goroutines来并行运行(或更精确地说是并发),但是以这种方式运行外部命令或应用程序则不需要您使用goroutines(实际上,这是多余的)。
这是因为exec.Cmd
用于运行命令的Cmd.Start()
方法具有启动指定命令但不等待其完成的方法。因此,当它在后台运行时,您可以自由地做其他事情,而当您需要等待它完成(并处理其结果)时,您可以调用Cmd.Wait()
(它将阻塞并等待命令完成)。
它看起来像这样:
cmd := exec.Command("npm", "install", "other_params")
cmd.Dir = entryPath
if err := cmd.Start(); err != nil {
log.Printf("Failed to start cmd: %v", err)
return
}
// Do other stuff while cmd runs in background:
log.Println("Doing other stuff...")
// And when you need to wait for the command to finish:
if err := cmd.Wait(); err != nil {
log.Printf("Cmd returned error: %v", err)
}
与相比,如果您不需要在“后台”中运行该命令Cmd.Start()
,那么Cmd.Run()
它将启动指定的命令并等待其完成。实际上Cmd.Run()
,无非就是链接Cmd.Start()
和Cmd.Wait()
调用。
请注意,在“后台”运行时,要获取应用程序的输出,您不能调用Cmd.Output()
或Cmd.CombinedOutput()
在它们运行时调用命令并获取其输出(并且您已经启动了命令)。如果需要命令的输出,请设置一个缓冲区,Cmd.Stdout
之后可以对其进行检查/使用。
这是可以做到的:
cmd := exec.Command("npm", "install", "other_params")
cmd.Dir = entryPath
buf := &bytes.Buffer{}
cmd.Stdout = buf
if err := cmd.Start(); err != nil {
log.Printf("Failed to start cmd: %v", err)
return
}
// Do other stuff while cmd runs in background:
log.Println("Doing other stuff...")
// And when you need to wait for the command to finish:
if err := cmd.Wait(); err != nil {
log.Printf("Cmd returned error: %v", err)
// You may decide to continue or return here...
}
fmt.Println("[OUTPUT:]", buf.String())
如果您还想捕获应用程序的标准错误流,则可能需要/进行相同的操作Cmd.Stderr
。提示:您可以将Cmd.Stdout
和设置相同的缓冲区Cmd.Stderr
,然后将获得合并的输出,这是根据doc保证的:
如果Stdout和Stderr是同一编写器,并且具有可以与==进行比较的类型,则一次最多只能有
一个goroutine调用Write。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句