2014-02-06 31 views
4

我正在尝试在Rust中编写一个shell。 shell的一个功能是能够将输入重定向到文件,重定向文件以输入,并将程序的输出传送到另一个程序。我使用std中的run::process_output函数来运行程序并获取它们的输出,但是我不知道如何在运行后像输入stdin一样发送输入。有什么方法可以创建一个直接连接到跑步程序的对象,并像输入stdin一样输入输入内容?如何通过标准输入发送到一个程序在Rust中

+0

可能'的std ::运行:: Process',你可以得到'Reader'和'作家'为'stdout'和'stdin' – Arjan

回答

1

您需要一个正在运行的进程的句柄才能完成此操作。

// spawn process 
let mut p = std::process::Command::new(prog).arg(arg).spawn().unwrap(); 
// give that process some input, processes love input 
p.stdin().get_mut_ref().write_str(contents); 
// wait for it to complete, you may need to explicitly close stdin above 
// i.e. p.stdin().get_mut_ref().close(); 
p.wait(); 

上面应该让你发送任意输入到一个进程。如果生成的进程读取到eof,就像许多程序一样,关闭stdin管道非常重要。

3

此程序演示了如何启动外部程序和流的标准输出 - >标准输入在一起:

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(); 
      } 
     } 
    } 
} 
0

迈克尔的回答的更新版本。如果你的输出/输入小,你可以将它读入以下方式的字符串和管道回:

let output = Command::new("ls").arg("-aFl") 
     .output().unwrap().stdout; 
let output = String::from_utf8_lossy(&output); 
println!("First program output: {:?}", output); 
let put_command = Command::new("my_other_program") 
     .stdin(Stdio::piped()) 
     .spawn().unwrap(); 
write!(put_command.stdin.unwrap(), "{}", output).unwrap(); 
相关问题