Is it possible to use process::Command and not wait?

#1

I am trying to write a little launcher app in Rust. I want it to start another program and then for the launcher to terminate and leave the program it launched still running.
I’ve looked at the docs for process::Command::spawn() but there doesn’t seem to be a ‘NO_WAIT’ option?

#2

You’ll get a Child handle as soon as the process has started. With that you can wait for completion, but that’s not required.

https://doc.rust-lang.org/std/process/struct.Child.html

There is no implementation of Drop for child processes, so if you do not ensure the Child has exited then it will continue to run, even after the Child handle to the child process has gone out of scope.

#3

I tried changing:

cmd.spawn()?;

to

let _child = cmd.spawn()?;

But it still seems to hang around.

#4

What do you mean by “seems to hang around”?

Also can you perhaps give a small self contained program that shows your problem?

for me this little sample seems to work properly:

use std::process::Command;

fn main() {
    if let Ok(mut c) = Command::new("sleep").arg("20").spawn() {
        println!("Spawned successfully");
        println!("Exit with: {:?}", c.wait());
    } else {
        panic!("panic");
    }
}
$ rust foo.rs
$ time ./foo
Spawned successfully
Exit with: Ok(ExitStatus(ExitStatus(0)))
./foo  0.00s user 0.00s system 0% cpu 20.007 total
1 Like
#5

Or if you remove that wait, the foo process will exit and leave the child running:

$ ./foo
Spawned successfully
$ pgrep -a sleep
19338 sleep 20
2 Likes
#6

I’m doing it on Windows with Rust 1.32, so maybe the behavior their is different.

#7

Ah, I think you would need CREATE_NEW_PROCESS_GROUP from here:

However, it’s not exposed:

In fact, I don’t see anything setting that flag internally either… :confused:

#8

Ah, you can manually set your own flags with this:
https://doc.rust-lang.org/std/os/windows/process/trait.CommandExt.html#tymethod.creation_flags

#9

I’ve now added the trait and now do:

let mut cmd = Command::new(...);
cmd.creation_flags(CREATE_NEW_PROCESS_GROUP);
cmd.arg(...);
let _child = cmd.spawn()?;

But it still holds on, i.e., I have to press Enter after running it in the cmd.exe conosle.

#10

I’m not sure – maybe you also need that DETACHED_PROCESS flag? or CREATE_NEW_CONSOLE? You can read about the creation flags here:
https://docs.microsoft.com/en-us/windows/desktop/ProcThread/process-creation-flags

#11

Can we do something automatically here in impl Drop for Child?

#12

Do you need to hit enter to close the terminal?

After spawning can you insert a printf! to verify if your program halts or not?

In windows many IDEs wrap terminal programs with another program that keeps the terminal open after exit, that the user can actually read the output of their program.

#13

I don’t use an IDE just gvim so I run it in the console.
I added a println!(“Running”); which outputs, then followed by the output of the prog I call which then waits for me to hit Enter to get back to the prompt. (The prog just prints text.)