管道

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), } }