How to save command stdout to a file?

Viewed 482

I'm writing a function that has a particular logging requirement. I want to capture the output from a Command::new() call and save it into a file. I'm just using echo here for simplicity's sake.

fn sys_command(id: &str) -> u64 {
    let mut cmd = Command::new("echo")
        .args(&[id])
        .stdout(Stdio::piped())
        .spawn()
        .expect("failed to echo");

    let stdout = cmd.stdout.as_mut().unwrap();
    let stdout_reader = BufReader::new(stdout);
    // let log_name = format!("./tmp/log/{}.log", id);
    // fs::write(log_name, &stdout_reader);
    println!("{:?}", stdout_reader.buffer());

    cmd.wait().expect("failed to call");
    id.parse::<u64>().unwrap()
}

How can I capture the output and save it to a file? I've made a playground here. My println! call returns [].

Even reading to another buffer prints the wrong value. Below, sys_command("10") prints 3. Here's an updated playground.

fn sys_command(id: &str) -> u64 {
    let mut buffer = String::new();
    let mut cmd = Command::new("echo")
        .args(&[id])
        .stdout(Stdio::piped())
        .spawn()
        .expect("failed to echo");

    let stdout = cmd.stdout.as_mut().unwrap();
    let mut stdout_reader = BufReader::new(stdout);
    let result = stdout_reader.read_to_string(&mut buffer);
    println!("{:?}", result.unwrap());

    cmd.wait().expect("failed to draw");
    id.parse::<u64>().unwrap()
}

What am I missing?

1 Answers

Instead of capturing the output in memory and then writing it to a file, you should just redirect the process's output to a file. This is simpler and more efficient.

    let log_name = format!("./tmp/log/{}.log", id);
    let log = File::create(log_name).expect("failed to open log");

    let mut cmd = Command::new("echo")
        .args(&[id])
        .stdout(log)
        .spawn()
        .expect("failed to start echo");

    cmd.wait().expect("failed to finish echo");

Even reading to another buffer prints the wrong value. Below, sys_command("10") prints 3.

This is unrelated — read_to_string() returns the number of bytes read, not the contents of them, and there are 3 characters: '1' '0' '\n'.

Related