如何在戈兰等待命令完成/直到几秒钟

  • 本文关键字:几秒 等待 命令 go
  • 更新时间 :
  • 英文 :


我正在运行命令exec.Command("cf api https://something.com/"),有时需要响应。但当执行此命令时,不会发生等待,而是立即执行并继续执行。我需要等待几秒钟,或者直到收到输出。如何做到这一点?

func TestCMDExex(t *testing.T) {
expectedText := "Success"
cmd := exec.Command("cf api https://something.com/")
cmd.Dir = "/root//"
out, err := cmd.Output()
if err != nil {
t.Fail()
}
assert.Contains(t, string(out), expectedText)
}

第一:创建cmd的正确方法是:

cmd := exec.Command("cf", "api", "https://something.com/")

子程序的每个参数都必须是一个单独的字符串。通过这种方式,您还可以传递包含空格的参数。例如,使用执行程序

cmd := exec.Command("cf", "api https://something.com/")

将一个命令行参数传递给cf;apihttps://something.com/",而传递两个字符串将传递两个自变量";api";以及";https://something.com/"。

在您的原始代码中,您正试图执行一个名为"的程序;cf apihttps://something.com/"。

然后你可以运行它并获得输出:

out, err:=cmd.Output()

这可以通过goroutine、通道和select语句来解决。下面的示例代码也进行错误处理:

func main() {
type output struct {
out []byte
err error
}
ch := make(chan output)
go func() {
// cmd := exec.Command("sleep", "1")
// cmd := exec.Command("sleep", "5")
cmd := exec.Command("false")
out, err := cmd.CombinedOutput()
ch <- output{out, err}
}()
select {
case <-time.After(2 * time.Second):
fmt.Println("timed out")
case x := <-ch:
fmt.Printf("program done; out: %qn", string(x.out))
if x.err != nil {
fmt.Printf("program errored: %sn", x.err)
}
}
}

通过选择exec.Command()中的3个选项之一,您可以看到代码以3种可能的方式运行:超时、正常子流程终止、错误子流程终止。

像往常一样,在使用goroutines时,必须小心确保它们终止,以避免资源泄漏。

还要注意,如果执行的子进程是交互式的,或者它将其进度打印到stdout,并且在执行过程中查看输出很重要,那么最好使用cmd.Run(),删除结构并只报告通道中的错误。

您可以使用go-waitGroup。这是我们将在每个goroutine中运行的函数。请注意,WaitGroup必须通过指针传递给函数。返回后,通知WaitGroup我们已经完成。睡眠来模拟一项昂贵的任务。(在您的情况下将其删除(此WaitGroup用于等待在此启动的所有goroutines完成。阻止,直到WaitGroup计数器返回0;所有的工人都通知他们完成了任务。

package main
import (
"fmt"
"sync"
"time"
)
func worker(id int, wg *sync.WaitGroup) {
defer wg.Done()
fmt.Printf("Worker %d startingn", id)
time.Sleep(time.Second)
fmt.Printf("Worker %d donen", id)
}
func main() {
var wg sync.WaitGroup
for i := 1; i <= 5; i++ {
wg.Add(1)
go worker(i, &wg)
}
wg.Wait()
}

最新更新