管道
The std::process::Child
struct represents a child process, and exposes the stdin
, stdout
and stderr
handles for interaction with the underlying process via pipes.
use std::io::prelude::*;
use std::process::{Command, Stdio};
static PANGRAM: &'static str =
"the quick brown fox jumps over the lazy dog\n";
fn main() {
// 启动 `wc` 命令
let mut cmd = if cfg!(target_family = "windows") {
let mut cmd = Command::new("powershell");
cmd.arg("-Command").arg("$input | Measure-Object -Line -Word -Character");
cmd
} else {
Command::new("wc")
};
let process = match cmd
.stdin(Stdio::piped())
.stdout(Stdio::piped())
.spawn() {
Err(why) => panic!("无法启动 wc:{}", why),
Ok(process) => process,
};
// 向 `wc` 的 `stdin` 写入字符串。
//
// `stdin` 的类型是 `Option<ChildStdin>`,但我们知道这个实例
// 必定存在,所以可以直接 `unwrap` 它。
match process.stdin.unwrap().write_all(PANGRAM.as_bytes()) {
Err(why) => panic!("无法写入 wc 的标准输入:{}", why),
Ok(_) => println!("已将 pangram 发送给 wc"),
}
// 由于 `stdin` 在上述调用后不再存活,它会被 `drop`,
// 管道随之关闭。
//
// 这一点非常重要,否则 `wc` 不会开始处理
// 我们刚刚发送的输入。
// `stdout` 字段的类型也是 `Option<ChildStdout>`,因此必须解包。
let mut s = String::new();
match process.stdout.unwrap().read_to_string(&mut s) {
Err(why) => panic!("无法读取 wc 的标准输出:{}", why),
Ok(_) => print!("wc 的响应为:\n{}", s),
}
}