Sven
Sven

Reputation: 11

Checking if exec.Command exited

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

Answers (2)

Sven
Sven

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

colm.anseo
colm.anseo

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

Related Questions