【发布时间】:2018-08-19 11:47:43
【问题描述】:
Rust 的 std::process::Command 允许通过 stdin 方法配置进程的标准输入,但该方法似乎只接受现有文件或管道。
给定一个字节,你将如何将它写入Command 的标准输入?
【问题讨论】:
标签: rust subprocess exec stdin
Rust 的 std::process::Command 允许通过 stdin 方法配置进程的标准输入,但该方法似乎只接受现有文件或管道。
给定一个字节,你将如何将它写入Command 的标准输入?
【问题讨论】:
标签: rust subprocess exec stdin
您可以创建一个标准输入管道并在其上写入字节。
Command::output 立即关闭标准输入时,您必须使用Command::spawn。Command::spawn 默认继承标准输入。您必须使用 Command::stdin 来更改行为。这里是示例 (playground):
use std::io::{self, Write};
use std::process::{Command, Stdio};
fn main() -> io::Result<()> {
let mut child = Command::new("cat")
.stdin(Stdio::piped())
.stdout(Stdio::piped())
.spawn()?;
let child_stdin = child.stdin.as_mut().unwrap();
child_stdin.write_all(b"Hello, world!\n")?;
// Close stdin to finish and avoid indefinite blocking
drop(child_stdin);
let output = child.wait_with_output()?;
println!("output = {:?}", output);
Ok(())
}
【讨论】:
child_stdin 只会删除引用。但不是实际的stdin。我认为这可以通过使用 take: if let Some(mut stdin) = child.stdin.take() { stdin.write_all(input.as_ref())?; // drop would happen here } 来解决
您需要在创建子流程时请求使用管道。然后您可以写入管道的写入端,以便将数据传递给子进程。
或者,您可以将数据写入临时文件并指定File 对象。这样,您不必将数据分段提供给子流程,如果您还从其标准输出中读取数据,这可能会有点棘手。 (有死锁的风险。)
如果继承描述符用于标准输入,则父进程不一定具有将数据注入其中的能力。
【讨论】: