【问题标题】:how to do a sandwich pipe in rust?夹层管生锈了怎么办?
【发布时间】:2021-09-20 04:36:40
【问题描述】:

我想创建一个 rust 程序,它通过管道从外部程序输入数据,并通过管道向另一个外部程序发送数据,就像三明治一样。更具体地说,我正在尝试创建的玩具模型是“gzip -cd input | rust | gzip -c -> output”。

基本上,我知道如何做第一部分(管道输入),例如:

   let child = match Command::new("zcat")
        .args(&["input"])
        .stdout(Stdio::piped())
        .stderr(Stdio::null())
        .spawn();
   let filehand = BufReader::new(child.stdout.unwrap());
   for line in filehand.lines() {
       ...
   }

但我被困在第二部分,也不知道如何将两者拼凑在一起。我知道 Perl 可以优雅地做到这一点:

open filehand_in, "gzip -cd input |";
open filehand_out, "| gzip -c - > output";
while ( <filehand_in> ) {
    # processing;
    print filehand_out ...;
}

优雅是指输入和输出的外部处理对主程序是透明:您只需将第一个管道视为标准输入,将第二个管道视为标准输出,无需担心.我想知道是否有人知道如何在 Rust 中实现类似的功能,谢谢。

【问题讨论】:

标签: rust subprocess pipe stdio spawn


【解决方案1】:

你可以这样做:

use std::io::{BufRead, BufReader, Write};
use std::process::{Command, Stdio};

pub fn main() {
    let mut left_child = Command::new("/bin/ls")
        .stdout(Stdio::piped())
        .spawn()
        .expect("failed to execute child");

    let mut right_child = Command::new("/bin/cat")
        .stdin(Stdio::piped())
        .spawn()
        .expect("failed to execute child");

    // extra scope to ensure that left_in and right_out are closed after
    // copying all available data
    {
        let left_in = BufReader::new(left_child.stdout.take().unwrap());
        let mut right_out = right_child.stdin.take().unwrap();
        for line in left_in.lines() {
            writeln!(&mut right_out, "{}", line.unwrap()).unwrap();
        }
    }
    let left_ecode = left_child.wait().expect("failed to wait on child");
    let right_ecode = right_child.wait().expect("failed to wait on child");

    assert!(left_ecode.success());
    assert!(right_ecode.success());
}

【讨论】:

    猜你喜欢
    • 2012-11-14
    • 2017-01-08
    • 2017-09-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-06-14
    • 2012-08-01
    • 1970-01-01
    相关资源
    最近更新 更多