I am attempting to write a shell in Rust. One of the functions of a shell is being able to redirect input to a file, redirect a file to input, and pipe output of a program into
This program demonstrates how you can launch external programs and stream their stdout -> stdin together:
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();
}
}
}
}