我试图在Rust写一个shell.shell的一个功能是能够将输入重定向到文件,将文件重定向到输入,以及将程序的输出管道输出到另一个程序.我正在使用run::process_output函数std来运行程序并获取它们的输出,但我不知道如何在运行之后将输入发送为程序员的stdin.有没有办法创建一个直接连接到run程序的对象,并像在stdin中输入一样输入输入?
该程序演示了如何启动外部程序并将它们的 stdout -> stdin 一起流式传输:
use std::io::{BufRead, BufReader, BufWriter, Write};
use std::process::{Command, Stdio};
fn main() {
// Create some argument vectors for lanuching external programs
let a = vec!["view", "-h", "file.bam"];
let outsam = vec!["view", "-bh", "-o", "rust.bam", "-"];
let mut child = Command::new("samtools")
.args(&a)
.stdout(Stdio::piped())
.spawn()
.unwrap();
let outchild = Command::new("samtools")
.args(&outsam)
.stdin(Stdio::piped())
.spawn()
.unwrap();
// Create a handle and writer for the stdin of the second process
let mut outstdin = outchild.stdin.unwrap();
let mut writer = BufWriter::new(&mut outstdin);
// Loop over the output from the first process
if let Some(ref mut stdout) = child.stdout {
for line in BufReader::new(stdout).lines() {
let mut l: String = line.unwrap();
// Need to add an end of line character back to the string
let eol: &str = "\n";
l = l + eol;
// Print some select lines from the first child to stdin of second
if (l.chars().skip(0).next().unwrap()) == '@' {
// convert the string into bytes and write to second process
let bytestring = l.as_bytes();
writer.write_all(bytestring).unwrap();
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
小智 5
您需要一个正在运行的进程的句柄才能执行此操作。
// spawn process
let mut p = std::process::Command::new(prog).arg(arg).spawn().unwrap();
// give that process some input, processes love input
p.stdin.as_mut().unwrap().write_str(contents);
// wait for it to complete, you may need to explicitly close stdin above
// i.e. p.stdin.as_mut().unwrap().close();
p.wait();
Run Code Online (Sandbox Code Playgroud)
上面应该允许您向进程发送任意输入。如果生成的进程像许多程序一样读取到 eof,则关闭 stdin 管道非常重要。