gpt4 book ai didi

rust - 从stderr读取时,为什么BufReader挂起?

转载 作者:行者123 更新时间:2023-12-03 11:44:38 24 4
gpt4 key购买 nike

我想执行一个命令,然后将任何潜在的输出捕获到stderr。这是我所拥有的:

if let Ok(ref mut child) = Command::new("ssh")
.args(&[
"some_args",
"more_args"
])
.stderr(Stdio::piped())
.spawn()
{
let output = child.wait().expect("ssh command not running");
let reader = BufReader::new(child.stderr.take().expect("failed to capture stderr"));
for line in reader.lines() {
match line {
Ok(line_str) => println!("output: {}", line_str);
Err(e) => println!("output failed!"),
}
}
}
我看到输出正在打印,但是程序随后挂起。我怀疑这可能与退出子进程有关,并且BufReader无法读取eof。一种解决方法是维护一个 let mut num_lines = 0;,然后在每次读取时增加它。在读取了x次之后,我进入了for循环,但这似乎不太干净。如何使BufReader正确完成阅读?

最佳答案

这些都不可能解决您的问题,但是无论如何,我都会提供建议:
Pipe-Wait-Read可能会死锁
调用child.wait()将阻止执行,直到子级退出,并返回退出状态。
使用Stdio::piped()为stdout/stderr流创建一个新管道,以便由应用程序处理。管道由操作系统处理,不是无限的。如果管道的一端正在写入数据,而另一端没有在读取数据,则它将最终阻止这些写入,直到读取某些内容为止。
该代码可能会死锁,因为您正在等待子进程退出,但是如果尝试写入已满且未被读取的输出管道,则该代码可能无法阻塞。
例如,这在我的系统(一个相当标准的ubuntu系统,具有用于管道的64KiB缓冲区)上陷入僵局:

// create a simple child proccess that sends 64KiB+1 random bytes to stdout
let mut child = Command::new("dd")
.args(&["if=/dev/urandom", "count=65537", "bs=1", "status=none"])
.stdout(Stdio::piped())
.spawn()
.expect("failed to execute dd");

let _status = child.wait(); // hangs indefinitely
let reader = BufReader::new(child.stdout.take().expect("failed to capture stdout"));
for _line in reader.lines() {
// do something
}
有很多选择:
  • 无需等待即可读取输出。 reader.lines()到达流末尾时将停止迭代。然后,如果您想知道退出状态,则可以调用child.wait()
  • 使用 .output() 代替.spawn()。这将阻塞,直到 child 退出并返回将完整的stdout/stderr流保存为OutputVec<u8>
  • 在等待 child 退出时,可以在单独的线程中处理输出流。如果听起来不错,请考虑使用 tokio::process::Command

  • 有关更多信息,请参见 How do I read the output of a child process without blocking in Rust?
    不要吞下 .lines()中的错误 reader.lines()返回一个迭代器,该迭代器为每一行产生一个结果。可能会处理的错误状态之一是,如果该行未正确进行utf-8编码,则将返回类似以下内容的内容:
    Err(
    Custom {
    kind: InvalidData,
    error: "stream did not contain valid UTF-8",
    },
    )
    但是,任何其他错误将直接来自基础阅读器,并且您可能不应该继续进行迭代。您收到的任何错误都不太可能恢复,并且肯定不会继续请求更多行。

    关于rust - 从stderr读取时,为什么BufReader挂起?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64398866/

    24 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com