如何捕获传输到Rust程序的进程的输出?

Abh*_*ckz 4 pipe rust rust-cargo

我知道如何读取命令行参数,但是我在从管道读取命令输出时遇到了困难.

  1. 使用管道连接将数据输出到Rust程序的程序(A):

    A | R
    
    Run Code Online (Sandbox Code Playgroud)
  2. 程序应该逐行消耗数据.

    $ pwd | cargo run应打印pwd输出.

    要么

    $ find . | cargo run应该输出find超过1行的命令输出.

Pet*_*all 7

您只需要从 中读取Stdin

这是基于文档中的示例:

use std::io;

fn main() {
    loop {
        let mut input = String::new();
        match io::stdin().read_line(&mut input) {
            Ok(len) => if len == 0 {
                return;
            } else {
                println!("{}", input);
            } 
            Err(error) => {
                eprintln!("error: {}", error);
                return;
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

它主要是包装在循环中的文档示例,当没有更多输入或出现错误时,会跳出循环。

其他更改是,在您的上下文中最好将错误写入stderr,这就是错误分支使用eprintln!, 而不是 的原因println!。在编写该文档时,该宏可能不可用。


She*_*ter 7

BufRead::lines标准输入锁定句柄上使用:

use std::io::{self, BufRead};

fn main() {
    let stdin = io::stdin();
    for line in stdin.lock().lines() {
        let line = line.expect("Could not read line from standard in");
        println!("{}", line);
    }
}
Run Code Online (Sandbox Code Playgroud)

如果你想重用它的分配String,你可以使用循环形式:

use std::io::{self, Read};

fn main() {
    let stdin = io::stdin();
    let mut stdin = stdin.lock(); // locking is optional

    let mut line = String::new();

    // Could also `match` on the `Result` if you wanted to handle `Err` 
    while let Ok(n_bytes) = stdin.read_to_string(&mut line) {
        if n_bytes == 0 { break }
        println!("{}", line);
        line.clear();
    }
}
Run Code Online (Sandbox Code Playgroud)