Interacting w/ a Spawned Process Till It's Done


#1

Hello all! I’ve been working on a project where I need to run the system’s package manager. As such I need to spawn the process and have it take take control of the session until it’s done installing packages. The problem I’ve been facing however is that I can’t seem to interact with the Command Struct in a non blocking way. I tried using CommandExt to change the session leader but then I get an error saying no tty available. This was about as close as I could find to what I needed but it wasn’t exactly what I wanted.

Put simply I want to start a process, switch out of my program to use it until it’s done, then jump back into the rust code again. Does anybody have any experience with this or be able to point me in the right direction to figure this out? It’s been driving me nuts and any help would be greatly appreciated.


#2

You say you want to interact in a “non-blocking way” but your description of what you want to happen sounds exactly like blocking. And a blocking solution does what you seem to ask for so simply, I must be misunderstanding you.

use std::process::{Command, Child, Output, ExitStatus};

fn main() {
    let mut apt_get: Command = Command::new("apt-get");
    apt_get.arg("upgrade");
    let child: Child = apt_get.spawn().unwrap(); // Process starts
    let result: Output = child.wait_with_output().unwrap(); // block until process is done
    let code: ExitStatus = result.status;
    let stdout: String = String::from_utf8(result.stdout).unwrap(); // stdout is Vec<u8>
    let stderr: String = String::from_utf8(result.stderr).unwrap();
    println!("Hello, apt! {}, stdout:{} stderr:{}", code, stdout, stderr);
}

When I run this (cargo run) apt-get takes the terminal for interaction, like the Y/N prompt before actually upgrading packages, (which I only get if I sudo cargo run) and after apt-get exits, the rust program prints its exit status. The stdout and stderr in result are empty, presumably because the default settings let it go to the terminal instead.

Could you explain the differences between what you want and this?