【问题标题】:Unable to read child stderr twice in Rust无法在 Rust 中两次读取子标准错误
【发布时间】:2022-01-16 05:31:15
【问题描述】:

由于某种原因,我第二次无法读取子进程stderr。这就是我所做的。

我正在为黄瓜测试生成一个子进程。在第一步中,我生成进程,获取它的stderr,保存它,然后从中读取。代码如下:

pub fn wait_process_output(
    reader: &mut BufReader<ChildStderr>,
    output: Vec<(String, u16)>,
) -> Result<(), String> {
    let mut process_output = String::new();
    loop {
        match reader.read_line(&mut process_output) {
            Err(e) => {
                return Err(format!("Unable to read output: {}", e));
            }
            Ok(_) => {
                // processing here
            }
        };
    }
}

pub fn step1(world: &mut TestWorld) {
    world.app_handler = Some(
        Command::new(&world.app_bin)
            .stderr(Stdio::piped())
            .spawn()
            .unwrap(),
    );
    let app_stderr = world.app_handler.as_mut().unwrap().stderr.take().unwrap();
    world.app_reader = Some(BufReader::new(app_stderr));
    wait_process_output(world.app_reader.as_mut().unwrap(), /* expected data */).ok();
}

此代码工作正常:stderr 正在按预期读取。

在第三个测试步骤中,我尝试再读取一次进程输出:

pub fn step3(world: &mut TestWorld) {
    wait_process_output(world.app_reader.as_mut().unwrap(), /* expected data */).ok();
}

这一次reader.read_line 无限挂起:什么都没有被读取。我确信子进程会产生一些输出:如果我分别在相同的条件下运行它,我可以看到它。

您能否提出任何想法,为什么我第二次尝试读取 BufReader 对象时它会损坏?

【问题讨论】:

  • step1() 一直读取到文件结束,因此step3() 中没有更多内容可读取。

标签: rust cucumber child-process stderr


【解决方案1】:

我找到了解决方案。问题是app 产生的输出早于step3 开始读取它。我认为针对这种情况实施了某种缓冲区,但似乎我错了。所以我最终使用了以下两种方法来解决我的问题:

pub fn wait_process_output(
    receiver: &Receiver<String>,
    output: Vec<(String, u16)>,
) -> Result<(), String> {
    loop {
        match receiver.try_recv() {
            // process output
        }
    }
}

pub fn start_listener(sender: Sender<String>, stream: ChildStderr) {
    spawn(move || {
        let mut f = BufReader::new(stream);
        loop {
            let mut buf = String::new();
            match f.read_line(&mut buf) {
                Ok(_) => {
                    sender.send(buf).unwrap();
                    continue;
                }
                Err(e) => {
                    println!("Unable to read process stderr: {:?}", e);
                    break;
                }
            }
        }
    });
}

【讨论】:

    猜你喜欢
    • 2011-08-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-09-15
    • 1970-01-01
    • 2021-03-24
    • 1970-01-01
    相关资源
    最近更新 更多