パイプ
std::process::Child 構造体は子プロセスを表し、パイプを介して基盤となるプロセスとやり取りするための stdin、stdout、stderr ハンドルを公開します。
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!("couldn't spawn wc: {}", why),
Ok(process) => process,
};
// 文字列を `wc` の `stdin` に書き込みます。
//
// `stdin` の型は `Option<ChildStdin>` ですが、このインスタンスには
// 必ずそれがあるとわかっているため、直接 `unwrap` できます。
match process.stdin.unwrap().write_all(PANGRAM.as_bytes()) {
Err(why) => panic!("couldn't write to wc stdin: {}", why),
Ok(_) => println!("sent pangram to wc"),
}
// 上記の呼び出し後、`stdin` は存続しないため `drop` され、
// パイプが閉じられます。
//
// これは非常に重要です。そうしないと、`wc` は今送信した入力の
// 処理を開始しません。
// `stdout` フィールドも型が `Option<ChildStdout>` なので、unwrap する必要があります。
let mut s = String::new();
match process.stdout.unwrap().read_to_string(&mut s) {
Err(why) => panic!("couldn't read wc stdout: {}", why),
Ok(_) => print!("wc responded with:\n{}", s),
}
}