在后台执行命令

tj holwik:

我使用以下代码,即“ npm install”的execute命令,现在在调试时,我看到该命令大约需要10..15秒的时间来执行(取决于我拥有多少模块)。我想要的是该命令将在后台执行,并且程序将继续。

cmd := exec.Command(name ,args...)
cmd.Dir = entryPath

在调试中,我看到要移至下一行tass大约10..15秒...

我有两个问题:

  1. 我该怎么办?因为我想并行地做某事...
  2. 我怎么知道什么时候结束?为了提供与此命令相关的其他逻辑,即npm install完成后,我需要做其他事情。
icza:

通常,您需要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] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章