Command - if a child process is asking for input, how to forward the question to the user

Hi,

I wrote a tiny wrapper around docker compose commands. It works perfectly, however once in a while one of the commands also asks for user input with a "[y/N]" question and currently this is causing my cli tool to hang without forwarding the question back to me.

This is the command code:

fn exec_command(cmd: &str, args: Vec<&str>) -> bool {
    let mut cli_command = Command::new(cmd)
        .args(&args)
        .stdout(Stdio::piped())
        .stderr(Stdio::piped())
        .spawn()
        .unwrap();

    for line_result in BufReader::new(cli_command.stdout.as_mut().unwrap()).lines() {
        match line_result {
            Ok(line) => {
                print!("{}", line);
                print!("\r\n");
            }
            Err(err) => {
                eprintln!("{}", err);
            }
        }
    }

    for line_result in BufReader::new(cli_command.stderr.as_mut().unwrap()).lines() {
        match line_result {
            Ok(line) => {
                print!("{}", line);
                print!("\r\n");
            }
            Err(err) => {
                eprintln!("{}", err);
            }
        }
    }

    cli_command.wait().unwrap().success()
}

I tried to add .stdin(Stdio:Piped()) but that didn't help.
How do I catch those requests for user input and forward them to the user?

It's likely because the question didn't print a newline at the end of the question since it's waiting for the user to input the answer. You probably need to find an alternative to lines that correctly handles this.

1 Like

Ok, having my facepalm moment.

@alice you were right! Thank you so much! Following your suggestion and some more helpful googling (thank you peeps of SO), I removed capturing of stdout line by line. All I wanted was to stream child process output to console as it was coming. The whole function is now a couple lines long and does everything I would expect it to!

pub fn exec_command(cmd: &str, args: Vec<&str>) -> bool {
    let mut cli_command = match Command::new(cmd)
        .args(&args)
        .stdin(Stdio::inherit())
        .stdout(Stdio::inherit())
        .stderr(Stdio::inherit())
        .spawn()
    {
        Err(err) => panic!("Error spawning: {}", err.description()),
        Ok(process) => process,
    };

    cli_command.wait().unwrap().success()
}

Cannot believe it! I've spent hours debugging this!

1 Like

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.