无法在 Rust 中两次读取子标准错误

Posted

技术标签:

【中文标题】无法在 Rust 中两次读取子标准错误【英文标题】:Unable to read child stderr twice in 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() 中没有更多内容可读取。 【参考方案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;
                
            
        
    );

【讨论】:

以上是关于无法在 Rust 中两次读取子标准错误的主要内容,如果未能解决你的问题,请参考以下文章

Rust编程语言入门之项目实例:- 命令行程序

在 Rust 中写入子进程的标准输入?

Rust语言教程 - 错误处理和可选值

确定子进程是不是从标准输入读取

在php中两次调用相同的函数时出错

错误 28105#0:*1 FastCGI 在标准错误中发送:“主要脚本未知”,同时从上游读取响应标头