Storing the result of a process::Output in a vec - lifetime issues

Hi! I'm trying to run multiple commands and store their output in a vec so I can work on the output lines later - but I am having issues putting them in to the vec inside a loop - output.stderr does not live long enough

let mut command_results = vec![];            
for target_subnet in options.targets.clone() {
    let output = Command::new("/usr/local/sbin/fping")
        .args(&["-q", "-r", "0", "-c", "5", "-g", &target_subnet])
        .output()
        .expect("failed to execute process");                    

    let output = String::from_utf8_lossy(&output.stderr);

    for line in output.lines() {
        command_results.push(line);           
    }
}
error[E0597]: `stderr` does not live long enough
  --> src/main.rs:55:54
   |
55 |                 let output = String::from_utf8_lossy(&stderr);
   |                                                      ^^^^^^^ borrowed value does not live long enough
...
60 |             }
   |             - `stderr` dropped here while still borrowed
...
73 |             for ping_result in command_results {
   |                                --------------- borrow later used here

I have tried cloning output but I get the same issue - how can I give ownership to the vec so it doesn't drop when the loop ends?

The simplest solution would be to convert each line from &str to an owned String, like this:

    for line in output.lines() {
        command_results.push(line.to_owned());           
    }

Thank you, that worked. I had assumed lines() would already give me Strings :relieved:

The iterator you get from lines() will yield &str slices. That way it borrows from the underlying text and you aren't making any unnecessary copies.

1 Like