Pearl: Pipe two `Command` together

A dive through the docs has left me scratching my head. Is it possible to chain two Command together, such that the output (stdout) of one becomes the input (stdin) of the other?

Please and thanks.

You should be able to create a pipe on stdout and pass it into the stdin of the other process (or vice versa). See the piped method for examples.

Actually, here is an example of two child processes being piped into each other.

3 Likes

That'll do it! Here's a snippet for Wanders from the Future:

fn piping() -> Result<(), Error> {
    let rg = std::process::Command::new("rg")
        .arg("toml")
        .stdin(std::process::Stdio::piped())
        .spawn()
        .unwrap();

    match std::process::Command::new("ls")
        .stdout(rg.stdin.unwrap())
        .output()
    {
        Err(e) => println!("{}", e),
        Ok(o) => {
            println!("STATUS: {}", o.status);
            println!("STDOUT: {}", String::from_utf8(o.stdout).unwrap());
            println!("STDERR: {}", String::from_utf8(o.stderr).unwrap());
        }
    }

    Ok(())
}

And other sample showing how to pipe to a child process's stdin from Rust itself:

fn pipe_from_rust() -> Result<(), Error> {
    let mut child = std::process::Command::new("rg")
        .arg("toml")
        .stdin(std::process::Stdio::piped())
        .stdout(std::process::Stdio::piped())
        .spawn()?;

    // Ensures that the handle to `stdin` drops and closes, avoiding a deadlock.
    {
        let mut stdin: std::process::ChildStdin = child.stdin.take().unwrap();
        writeln!(stdin, "Cargo.toml")?;
        writeln!(stdin, "Blah.toml")?;
    }

    match child.wait_with_output() {
        Err(e) => println!("Error: {}", e),
        Ok(o) => {
            println!("STATUS: {}", o.status);
            println!("STDOUT: {}", String::from_utf8(o.stdout).unwrap());
            println!("STDERR: {}", String::from_utf8(o.stderr).unwrap());
        }
    }

    Ok(())
}

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.