How to cast a vect<u8> to a stream of utf-8 characters?
I'm trying to analyse, line-per-line, the ouput of a subprocess:
let mut amulecmd = Command::new("amulecmd")
.stdin(Stdio::piped())
.stdout(Stdio::piped())
.spawn()
.unwrap();
let amulecmd_stdin = amulecmd.stdin.as_mut().unwrap();
match amulecmd_stdin.write_all( b"show dl\nquit" ) {
Ok(_) => {
let status = amulecmd.wait_with_output();
let reader = BufReader::new(status.unwrap().stdout);
for line in reader.lines() {
// TODO: if line is a "data" line
// split it into fields
println!("{}", line);
}
},
Err(error) => panic!("Unable to write to amulecmd stdin: {:?}", error),
};
The line let reader = BufReader::new(status.unwrap().stdout);
doesn't compile:
error[E0277]: the trait bound `Vec<u8>: std::io::Read` is not satisfied
--> src/main.rs:64:38
|
64 | let reader = BufReader::new(status.unwrap().stdout);
| -------------- ^^^^^^^^^^^^^^^^^^^^^^ the trait `std::io::Read` is not implemented for `Vec<u8>`
| |
| required by a bound introduced by this call
|
note: required by a bound in `BufReader::<R>::new`
--> /home/aubin/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/std/src/io/buffered/bufreader.rs:55:9
|
55 | impl<R: Read> BufReader<R> {
| ^^^^ required by this bound in `BufReader::<R>::new`
I'm looking for a general purpose solution, I don't want to load all the lines into a single string because I have to deal with processes which runs forever or networks streams never closed.
Have a look at the stdout
field. It has type Option<ChildStdout>
, and ChildStdout
implements Read
.
If you want to stream the command's output, don't call wait_with_output
, as that accumulates all the remaining output into an Output
, which as you said you don't want to do. Instead perhaps use try_wait
if you need to check if the command has ended without blocking. Or possibly reaching the end of the stdout stream will indicate that it exited -- I haven't tried it myself and the documentation doesn't say outright.