第二次将 stdout 重定向到 stderr 时崩溃

Crash when redirecting stdout to stderr for a second time

foo() 的第二个 运行 将在没有错误消息的情况下崩溃。当我删除此 unsafe 行时,它工作正常。

use std::process::{Command, Stdio};
use std::os::unix::io::FromRawFd;

fn foo() {
    let mut p = Command::new("ls");
    unsafe { p.stdout(Stdio::from_raw_fd(2)) };
    let mut child = p.spawn().expect("spawn error");
    child.wait().expect("wait error");
    println!("process: {:?}", p);
}

fn main() {
    foo();
    foo();
}
  1. 这里的 unsafe 代码似乎有问题。也许它没有释放一些资源?
  2. 有没有办法在不使用不安全代码的情况下执行 stdout -> stderr 重定向?

Stdio::from_raw_fd(2) 将文件描述符 2 的所有权赋予新构造的 Stdio 对象。 Stdio 的析构函数将关闭文件描述符。当 Command 被删除时,Stdio 的析构函数将 运行,因为 Command 拥有 Stdio.

当然,您在第二次调用 foo 时没有得到任何输出的原因是标准错误已关闭!

简单的解决方案是复制文件描述符 2 并将副本传递给 Stdio::from_raw_fd