【问题标题】:How would you stream output from a Process in Rust?你将如何在 Rust 中流式传输进程的输出?
【发布时间】:2014-10-24 15:16:36
【问题描述】:

此问题涉及截至 2014 年 10 月的 Rust。

如果您使用的是 Rust 1.0 或更高版本,您最好在别处寻找解决方案。


我有一个长时间运行的 Rust 进程,它会生成日志值,我正在使用 Process 运行它。

它看起来虽然我可以使用set_timeout()wait() 定期“检查”正在运行的进程并执行某种高级循环,例如:

let mut child = match Command::new("thing").arg("...").spawn() {
    Ok(child) => child,
    Err(e) => fail!("failed to execute child: {}", e),
};
loop {
    child.set_timeout(Some(100));
    match child.wait() {
        // ??? Something goes here
    }
}

我不是 100% 了解的事情是;如何区分来自wait() 的超时错误和进程返回错误,以及如何使用PipeStream 在每个间隔推出时“尽可能多地读取而不阻塞流”。

这是最好的方法吗?我应该开始一个任务来监视 stdout 和 stderr 吗?

【问题讨论】:

    标签: rust rust-obsolete


    【解决方案1】:

    为了区分进程中的错误和超时,你必须管理等待的返回,这里有一个例子:

    fn run() {
        let mut child = match Command::new("sleep").arg("1").spawn() {
            Ok(child) => child,
            Err(e) => fail!("failed to execute child: {}", e),
        };
        loop {
            child.set_timeout(Some(1000));
            match child.wait() {
                // Here assume any error is timeout, you can filter from IoErrorKind
                Err(..) => println!("Timeout"),
                Ok(ExitStatus(0)) => {
                    println!("Finished without errors");
                    return;
                }
                Ok(ExitStatus(a)) => {
                    println!("Finished with error number: {}", a);
                    return;
                }
                Ok(ExitSignal(a)) => {
                    println!("Terminated by signal number: {}", a);
                    return;
                }
            }
        }
    }
    

    关于使用流,检查 wait_with_output,或使用通道和线程实现类似的东西:http://doc.rust-lang.org/src/std/home/rustbuild/src/rust-buildbot/slave/nightly-linux/build/src/libstd/io/process.rs.html#601

    希望对你有帮助

    【讨论】:

    • 那个 wait() 东西是正确的,但是 wait_with_output 在它返回任何东西之前读取整个结果,这正是我在这种情况下不能做的(它使用通道实现...)
    • 您可以将read_to_end 调用更改为read(length) 或更方便您找到的。
    【解决方案2】:

    看看货物:

    https://docs.rs/cargo-util/0.1.1/cargo_util/struct.ProcessBuilder.html#method.exec_with_streaming

    唯一的缺点是cargo-util 似乎需要openssl,即使是default-features=false...

    但你至少可以看到它和read2 是如何完成的。

    【讨论】:

      猜你喜欢
      • 2015-11-06
      • 2017-04-29
      • 2015-03-21
      • 1970-01-01
      • 2011-03-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-01-07
      相关资源
      最近更新 更多