Pipes

The std::Child struct represents a running child process, and exposes the
stdin, stdout and stderr handles for interaction with the underlying
process via pipes.

  1. use std::error::Error;
  2. use std::io::prelude::*;
  3. use std::process::{Command, Stdio};
  4. static PANGRAM: &'static str =
  5. "the quick brown fox jumped over the lazy dog\n";
  6. fn main() {
  7. // Spawn the `wc` command
  8. let process = match Command::new("wc")
  9. .stdin(Stdio::piped())
  10. .stdout(Stdio::piped())
  11. .spawn() {
  12. Err(why) => panic!("couldn't spawn wc: {}", why.description()),
  13. Ok(process) => process,
  14. };
  15. // Write a string to the `stdin` of `wc`.
  16. //
  17. // `stdin` has type `Option<ChildStdin>`, but since we know this instance
  18. // must have one, we can directly `unwrap` it.
  19. match process.stdin.unwrap().write_all(PANGRAM.as_bytes()) {
  20. Err(why) => panic!("couldn't write to wc stdin: {}",
  21. why.description()),
  22. Ok(_) => println!("sent pangram to wc"),
  23. }
  24. // Because `stdin` does not live after the above calls, it is `drop`ed,
  25. // and the pipe is closed.
  26. //
  27. // This is very important, otherwise `wc` wouldn't start processing the
  28. // input we just sent.
  29. // The `stdout` field also has type `Option<ChildStdout>` so must be unwrapped.
  30. let mut s = String::new();
  31. match process.stdout.unwrap().read_to_string(&mut s) {
  32. Err(why) => panic!("couldn't read wc stdout: {}",
  33. why.description()),
  34. Ok(_) => print!("wc responded with:\n{}", s),
  35. }
  36. }