Reputation: 11
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?
Upvotes: 0
Views: 1565
Reputation: 11
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")
}
}
Upvotes: 0
Reputation: 22037
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.
Upvotes: 2