Hello,
I'm trying to read stdout
of another process, which is writing to stdout every second. I'd like to read each line and print it out modified on the stdout of my main process.
I used std::process:Command
to do so. The rust code is this one :
use std::{error::Error, io::{BufRead, ErrorKind}, process::{Command, Stdio}};
use std::io::BufReader;
fn output() -> Result<(), Box<dyn Error>> {
let stdout = Command::new("./test")
.stdout(Stdio::piped())
.spawn()?
.stdout
.ok_or_else(|| std::io::Error::new(ErrorKind::Other, "Could not capture standard output."))?;
let reader = BufReader::new(stdout);
reader
.lines()
.filter_map(|line| line.ok())
.for_each(|line| println!("hello {}", line));
Ok(())
}
fn main() {
output().unwrap();
println!("Hello, world!");
}
And the test
application it runs is written in c. It looks like this :
#include <stdio.h>
#include <unistd.h>
int main(int argc, char**argv)
{
for (int i = 0; i < 10; i++) {
fprintf(stdout, "World! %d\n", i);
usleep(1000000);
}
return 0;
}
If I run the rust code like this, I got all the output after 10seconds, as a block. it doesn't print line by line. Whereas if I add fflush(stdout)
in the C code, I print line by line.
My guess is that the BufReader is filled when the application exits instead of being filled when a 0xA is received as mentioned in the documentation : BufRead in std::io - Rust
I wonder if there is a way to get the line by line behavior with my Rust code.
Thanks,
Nicolas