我试图在这些情况下检查exec.Cmd
是否正在运行:
如果它正在运行,这将允许我终止此命令,以便我可以使用不同的参数再次启动它。
以下简单用例:
c := exec.Command("omxplayer", "video.mp4")
s, _ := c.StdinPipe() // use the pipe to send the "q" string to quit omxplayer
log.Printf("Running (false): %v\n", checkRunning(c)) // prints false: command has not started yet
c.Start()
log.Printf("Running (true): %v\n", checkRunning(c)) // print true: command has started
time.AfterFunc(3*time.Second, func() {
log.Println("about to quit process...")
log.Printf("Running (true): %v\n", checkRunning(c)) // prints true: command still running at this point
s.Write([]byte("q"))
})
log.Println("waiting for command to end")
log.Printf("Running (true): %v\n", checkRunning(c)) // prints true: command still running at this point
c.Wait()
log.Println("command should have ended by now")
log.Printf("Running (false): %v\n", checkRunning(c)) // prints false: command ended at this point
这是我能想到的最好的:
func checkRunning(cmd *exec.Cmd) bool {
if cmd == nil || cmd.ProcessState != nil && cmd.ProcessState.Exited() || cmd.Process == nil {
return false
}
return true
}
它适用于上面的用例,但它似乎过于复杂,我不确定它有多可靠。
有更好的方法吗?
答案 0 :(得分:5)
也许在goroutine中同步运行并将结果放在您可以选择的频道上?
c := exec.Command("omxplayer", "video.mp4")
// setup pipes and such
ch := make(chan error)
go func(){
ch <- c.Run()
}()
select{
case err := <- ch:
// done! check error
case .... //timeouts, ticks or anything else
}
答案 1 :(得分:0)
对于我来说,一个与captncraig的答案略有不同的方法:
c := exec.Command("omxplayer", "video.mp4")
err := c.Start() // starts the specified command but does not wait for it to complete
// wait for the program to end in a goroutine
go func() {
err := c.Wait()
// logic to run once process finished. Send err in channel if necessary
}()