Search code examples
rustcommand-line

Running a command with timeout


I'm translating a command line program from Python to Rust.

The program has to run different commands that could not terminate.

The Python version uses subprocess.run() that accepts timeout as argument.

For example:

result = subprocess.run(["java", "MyProgram"],
                        timeout=timeout,
                        capture_output=True)

When translating into Rust, I'm using:

let out = Command::new("java")
    .arg("MyProgram")
    .output()?;

But as long as I know, Command is not allowing me to specify any timeout.

Since it will run on GNU/Linux, I could simply wrap the call with timeout (as in timeout 10 java MyProgram) but I wonder if there's any solution that does not depend on timeout.

So the question is: how do I run a command from Rust with a timeout?


Solution

  • There's a few ways you could handle this.

    One would be to start a background thread and use Child::kill() to kill the process after a timeout. You would need to use Arc to share the object between threads. This is a bit problematic though because the methods of Child require a mutable reference to the Child, so you can't wait on the process from one thread at the same time as you try to kill it from another.

    Another approach would be to use Child::try_wait() in a spinloop and kill the process when the wall clock has passed a threshold time.

    Alternatively, consider using the wait_timeout crate, which wraps up this complexity behind a simple function.