How do I prefix Command stdout with [stdout] and [

2019-07-21 10:17发布

Using the Command struct, how can I add a prefix to the stdout and stderr buffers?

I would like the output to look something like this:

[stdout] things are good.
[sterr] fatal: repository does not exist.

This would also be nice to apply to the program's main stdout so anything the program prints is prefixed like that.

Here is the code I currently have:

let output = Command::new("git").arg("clone").output().unwrap_or_else(|e| {
    panic!("Failed to run git clone: {}", e)
});

标签: rust
1条回答
在下西门庆
2楼-- · 2019-07-21 10:57

I don't believe you can do what you truly want to do right now. Ideally, you'd be able to provide an implementor of Write to the Process::stdout method. Unfortunately, the set of choices for Stdio is sparse. Perhaps you can campaign to have this be a feature request for Rust 1.1, or create a crate to start fleshing out some of the details (like cross-platform compatibility)

If it is acceptable to remove the interleaving of stdout / stderr, then this solution could help:

use std::io::{BufRead,BufReader};
use std::process::{Command,Stdio};

fn main() {
    let mut child =
        Command::new("/tmp/output")
        .stdout(Stdio::piped())
        .stderr(Stdio::piped())
        .spawn().unwrap();

    if let Some(ref mut stdout) = child.stdout {
        for line in BufReader::new(stdout).lines() {
            let line = line.unwrap();
            println!("[stdout] {}", line);
        }
    }

    if let Some(ref mut stderr) = child.stderr {
        for line in BufReader::new(stderr).lines() {
            let line = line.unwrap();
            println!("[stderr] {}", line);
        }
    }

    let status = child.wait().unwrap();
    println!("Finished with status {:?}", status);
}
查看更多
登录 后发表回答