第二次将 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();
}
- 这里的
unsafe
代码似乎有问题。也许它没有释放一些资源?
- 有没有办法在不使用不安全代码的情况下执行 stdout -> stderr 重定向?
Stdio::from_raw_fd(2)
将文件描述符 2 的所有权赋予新构造的 Stdio
对象。 Stdio
的析构函数将关闭文件描述符。当 Command
被删除时,Stdio
的析构函数将 运行,因为 Command
拥有 Stdio
.
当然,您在第二次调用 foo
时没有得到任何输出的原因是标准错误已关闭!
简单的解决方案是复制文件描述符 2 并将副本传递给 Stdio::from_raw_fd
。
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();
}
- 这里的
unsafe
代码似乎有问题。也许它没有释放一些资源? - 有没有办法在不使用不安全代码的情况下执行 stdout -> stderr 重定向?
Stdio::from_raw_fd(2)
将文件描述符 2 的所有权赋予新构造的 Stdio
对象。 Stdio
的析构函数将关闭文件描述符。当 Command
被删除时,Stdio
的析构函数将 运行,因为 Command
拥有 Stdio
.
当然,您在第二次调用 foo
时没有得到任何输出的原因是标准错误已关闭!
简单的解决方案是复制文件描述符 2 并将副本传递给 Stdio::from_raw_fd
。