我看到两种方法(Rust v0.9)。对于下面的示例,假设我想将STDOUT重定向到某个文件。
第一个是获取文件的文件描述符,然后将其传递给std::run::ProcessOptions
结构。以下是std::run::process_status
的用法:
let mut opt_prog = Process::new(prog, args, ProcessOptions {
env: None,
dir: None,
in_fd: Some(unsafe { libc::dup(libc::STDIN_FILENO) }),
out_fd: Some(unsafe { libc::dup(libc::STDOUT_FILENO) }),
err_fd: Some(unsafe { libc::dup(libc::STDERR_FILENO) })
});
它获取STDIN,STDOUT和STDERR的常用文件描述符并设置它们。 但是如何获取Rust中打开的任意文件的文件描述符?我还没有找到办法。
第二个选项是通过ProcessOptions::new()
使用默认的ProcessOptions,它打开一个到stdin,stdout和stderr的管道,让你抓住它们,如下所示:
let pgm = "ls";
let args = ~[~"-lh"];
match Process::new(pgm, args, ProcessOptions::new()) {
None => println("fubar"),
Some(mut p) => {
{
let process = &mut p;
let rdr = process.output(); // grab STDOUT output
let out = rdr.read_to_str();
// write output to your file of choice here
}
p.close_input();
p.close_outputs();
p.finish();
}
}
我更喜欢第一种方式,但我怀疑第二种方式是采用这种方式。
我不喜欢第二个选项是如果我只想重定向STDOUT而不是其他选项?我现在必须调用process.error()
并将其写回STDERR,这看起来很愚蠢。我也必须为STDIN做类似的事情,因为它也被包裹在管道中。
关于最好方法的想法?
答案 0 :(得分:2)
使用std::os::unix::AsRawFd
特征,它使用std::io::fs::File
方法扩展与平台无关的as_raw_fd
以返回文件描述符。
使用此扩展程序和其他特定于Unix的扩展程序的一种便捷方法是导入std::os::unix::prelude
模块。特别是,我最初回答这个问题的例子实际上与文档中的example几乎相同:
#![feature(globs)]
use std::io::fs::File;
use std::os::unix::prelude::*;
fn main() {
let p = Path::new("/etc/passwd");
let f = File::open(&p).unwrap();
let fd = f.as_raw_fd();
println!("{} fd: {}", p.as_str().unwrap(), fd);
}