Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

파이프

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` 명령어를 실행(spawn)합니다
    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!("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!("wc의 표준 출력을 읽을 수 없습니다: {}", why),
        Ok(_) => print!("wc의 응답:\n{}", s),
    }
}