如何将输入发送到使用Command创建的进程的stdin并捕获输出(和状态)

时间:2020-09-17 09:41:01

标签: rust

我希望使用Command创建一个子进程,从我创建的另一个子进程中将其输入stdin,然后等待并捕获输出。

我还看到了关于一个或另一个的其他问题和答案,但没有同时出现。

我要尝试的顺序是:

  • 创建目标子命令,标准输入为Piped()
  • 使用spawn()产生孩子并让孩子回来
  • 从Child中获取“ stdin”字段以与缓冲区编写器一起使用
  • 使用stdout Piped()生成数据处理的源
  • 将源标准输出的输出循环到目标的标准输入
  • 然后尝试使用wait_with_output()捕获目标的输出

最后一步没有编译,因为它说当我得到标准输入时,子对象已移动(消耗)。

游乐场link

1 个答案:

答案 0 :(得分:1)

您需要拥有dest_child.stdin管道的所有权才能将对象分配给BufWriter::new。由于管道位于Option内,因此您可以使用Option::take将其移出而无需离开dest_child“部分移动”。您的代码的另一个问题是必须dest.stdin而不是继承的管道,否则dest_child.stdin将仅保留None。完成这些更改后,您的代码就会编译并运行(playground)。

但是,请注意,无需手动将数据从一个进程传输到另一个进程,操作系统完全有能力自行执行此操作。例如(playground):

use std::process::{Command, Stdio};

fn main() {
    let mut dest = Command::new("wc")
        .stdin(Stdio::piped())
        .stdout(Stdio::piped())
        .spawn()
        .unwrap();
    let _source = Command::new("ls")
        .stdout(dest.stdin.take().unwrap())
        .spawn()
        .unwrap();
    let dest_output = dest.wait_with_output().unwrap();

    match dest_output.status.code() {
        Some(0) => println!("OK: {}", String::from_utf8_lossy(&dest_output.stdout)),
        Some(code) => println!("Error {}", code),
        None => {}
    }
}
相关问题