I've been playing around with Rust lately and I am trying to run a async command with tokio. My goal is to read stdout/err live and be able to pass messages to the process if needed. I do not depend on tokio, and if there is a better way of doing this, please advise.
I am using tokio process::Command to create a child process and than transform it into stream and read from it, but if the process is continuous I am getting no stdout/err. Here is what I have been playing around with (used python as continuously running process):
use std::process::Stdio; use tokio_stream::StreamExt; use tokio_util::codec::{FramedRead, LinesCodec, FramedWrite}; let mut process = tokio::process::Command::new("sh") .arg("-c") .arg("python3") .stdout(Stdio::piped()) .stderr(Stdio::piped()) .stdin(Stdio::piped()) .spawn() .unwrap(); let stdout = FramedRead::new(process.stdout.take().unwrap(), LinesCodec::new()) .map(|data| data.expect("fail on out!")); let stderr = FramedRead::new(process.stderr.take().unwrap(), LinesCodec::new()) .map(|data| data.expect("fail on err!")); let mut stream = stdout.chain(stderr); while let Some(msg) = stream.next().await { println!("{:?}", msg); } I also tried waiting for the process with output, where I get empty stdout and stderr - not entierly sure why. When I execute the process without piping stderr/out/in I get the usual initial responses from python.
Cargo.toml dependencies for ref:
tokio = {version="1.26", features = ["rt", "macros", "rt-multi-thread", "fs", "process", "io-std", "io-util"]} tokio-util = { version="0.7.7", features = ["codec", "io"]} tokio-stream = "0.1.12"
chain()"emits elements from the first stream, and when first stream reaches the end, emits the elements from the second stream.". That means you are not reading anything from stderr until stdout is closed. Python likely tries to first write its "welcome message" to stderr, but nothing reads it, so it ends up blocked forever.echo "foo\n" | python3in a termial and you can observe that it does not print out a prompt. I would first recommend to edit your question to be a MCVE (currently imports are not listed, dependencies seem to be missing, e.g.map()is not found). 2. Try to get reading stdout/stderr working with a non-interactive program (one that does not switch behavior depending on whether a TTY is attached or not).