Support for continuous stdin for a long-running process.
For a long-running process (a shell), I would like to provide multiple commands over time and read their output, respectively.
Would it be it somehow possible to provide input, that is not one-time like stdin_bytes()? (Maybe by creating a pipe and passing it as stdin_file?)
Maybe by creating a pipe and passing it as
stdin_file
Yep, that's exactly what you'd want to do in this case. Here's an example of doing this with Duct:
use duct::cmd;
use std::error::Error;
use std::io::prelude::*;
fn main() -> Result<(), Box<dyn Error>> {
let (read_pipe, mut write_pipe) = os_pipe::pipe()?;
let handle = cmd!("wc").stdin_file(read_pipe).start()?;
for _ in 0..10 {
write_pipe.write_all(b"foobarbaz")?;
}
// Important: If we don't close our write end first, wc will wait for more input forever, and
// handle.wait() will never return.
drop(write_pipe);
handle.wait()?;
Ok(())
}
And for comparison here's an example of the same thing with std::process::Command:
use std::error::Error;
use std::io::prelude::*;
use std::process::{Command, Stdio};
fn main() -> Result<(), Box<dyn Error>> {
let mut handle = Command::new("wc").stdin(Stdio::piped()).spawn()?;
let mut write_pipe = handle.stdin.take().unwrap();
for _ in 0..10 {
write_pipe.write_all(b"foobarbaz")?;
}
// Important: If we don't close our write end first, wc will wait for more input forever, and
// handle.wait() will never return.
drop(write_pipe);
handle.wait()?;
Ok(())
}
One difference to be aware of between stdin_bytes and stdin_file is that the former spawns a thread for you to do the writing in the background. That's a bit expensive, but it avoids some potentially confusing deadlocks in more complex use cases. See https://github.com/oconnor663/duct.py/blob/master/gotchas.md#using-io-threads-to-avoid-blocking-children