英文:
Checking if exec.Command exited
问题
我正在尝试编写一个程序,可以运行一个可执行文件,并在2秒内获取可执行文件是否退出。
files, _ := ioutil.ReadDir("Files/")
for _, f := range files {
cmd := exec.Command(fmt.Sprint("Files/", f.Name()))
cmd.Start()
time.Sleep(2 * time.Second)
if cmd.ProcessState.Exited() {
fmt.Println("Exited")
} else {
fmt.Println("Not exited")
}
}
这段代码会导致一个panic: runtime error: invalid memory address or nil pointer dereference
错误,因为cmd.ProcessState
还没有被设置(如果使用cmd.Run()
则可以工作,但这违背了整个目的)。我尝试搜索其他方法,但找不到其他方法。
是否有其他方法可以实现这个功能?如果有,如何使用它?
英文:
I'm trying to make a program that can run an executable, and get if the executable exited in 2 seconds
files, _ := ioutil.ReadDir("Files/")
for _, f := range files {
cmd := exec.Command(fmt.Sprint("Files/", f.Name()))
cmd.Start()
time.Sleep(2 * time.Second)
if cmd.ProcessState.Exited() {
fmt.Println("Exited")
} else {
fmt.Println("Not exited")
}
}
This gives a panic: runtime error: invalid memory address or nil pointer dereference
Because it isn't set yet (If I use cmd.Run()
it works but that defeats the whole purpose). I've tried searching for other ways to do it but I can't find any other ways.
Are there any other ways to do this? And if so, how do I use it?
答案1
得分: 2
始终检查错误。
来自 cmd.Start 文档
> 如果 Start 返回成功,c.Process 字段将被设置。
因此,请确保 cmd.Start
没有出错:
err := cmd.Start()
if err != nil {
log.Fatalf("cmd.Start 错误: %v", err)
}
还有来自 exec.Cmd 文档:
// ProcessState 包含有关已退出进程的信息,
// 在调用 Wait 或 Run 后可用。
ProcessState *os.ProcessState
// 包含已过滤或未导出的字段
因此,如果进程尚未完成,则 ProcessState
将为 nil - 因此您将得到一个运行时 panic。
英文:
Always check errors.
From cmd.Start docs
> If Start returns successfully, the c.Process field will be set.
so ensure cmd.Start
is not erroring:
err := cmd.Start()
if err != nil {
log.Fatalf("cmd.Start error: %v", err)
}
also from the exec.Cmd docs:
// ProcessState contains information about an exited process,
// available after a call to Wait or Run.
ProcessState *os.ProcessState
// contains filtered or unexported fields
so if the process has not completed then ProcessState
will be nil - and thus you will get a runtime panic.
答案2
得分: 0
这对我有用:
files, _ := ioutil.ReadDir("Files/")
for _, f := range files {
cmd := exec.Command(fmt.Sprint("Files/", f.Name()))
cmd.Start()
time.Sleep(2 * time.Second)
check, _ := exec.Command("tasklist", "/FI", "PID eq "+fmt.Sprint(cmd.Process.Pid)).Output()
output := string(check)
if strings.HasPrefix(output, "INFO: No tasks are running") {
fmt.Println("Exited")
} else {
fmt.Println("Still running")
}
}
英文:
This worked for me:
files, _ := ioutil.ReadDir("Files/")
for _, f := range files {
cmd := exec.Command(fmt.Sprint("Files/", f.Name()))
cmd.Start()
time.Sleep(2 * time.Second)
check, _ := exec.Command("tasklist", "/FI", "PID eq "+fmt.Sprint(cmd.Process.Pid)).Output()
output := string(check)
if strings.HasPrefix(output, "INFO: No tasks are running") {
fmt.Println("Exited")
} else {
fmt.Println("Still running")
}
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论