如何用时雄(Rust)读取连续进程的stdout/err流(并将args传递回它)?

7kjnsjlb  于 2023-04-30  发布在  其他
关注(0)|答案(1)|浏览(171)

我最近一直在玩Rust,我试图用时雄运行async命令。**我的目标是实时读取stdout/err,并能够在需要时向进程传递消息。**我不依赖时雄,如果有更好的方法,请建议。
我使用时雄process::Command创建一个子进程,然后将其转换为流并从中读取,但如果进程是连续的,我就不会得到stdout/err。下面是我一直在玩的东西(使用python作为持续运行的进程):

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);
    }

我还尝试等待进程的输出,在那里我得到空的stdout和stderr -不完全知道为什么。当我在不使用管道stderr/out/in的情况下执行进程时,我从python获得了通常的初始响应。
引用的Cargo.toml依赖项:

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"
qvtsj1bj

qvtsj1bj1#

该问题是由于我用于测试的过程造成的。当用另一个进程测试时,不检查是否直接调用它,一切正常。
在评论中提供了信息:

  • FWIW,Python也试图变得聪明,如果它检测到stdin不是TTY(?),它不会以交互模式启动。试试echo“foo\n”|python3在termial中,你可以观察到它不会打印出提示符。我首先建议将您的问题编辑为MCVE(目前未列出导入,依赖项似乎缺失,e.例如,map()未找到)。2.尝试阅读stdout/stderr与非交互式程序(不根据是否连接TTY切换行为的程序)一起工作。- 贾斯汀斯

相关问题