From 9eef6fcafaec6515eb4af8e981657072980a8645 Mon Sep 17 00:00:00 2001 From: Julio Biason Date: Thu, 31 Aug 2023 14:15:03 -0300 Subject: [PATCH] Spawn a thread to capture and process the output --- commandtest/Cargo.lock | 7 +++++++ commandtest/src/main.rs | 31 +++++++++++++++++++++++++++++-- commandtest/src/the_script.sh | 26 +++++++++++++++++--------- 3 files changed, 53 insertions(+), 11 deletions(-) create mode 100644 commandtest/Cargo.lock diff --git a/commandtest/Cargo.lock b/commandtest/Cargo.lock new file mode 100644 index 0000000..764966e --- /dev/null +++ b/commandtest/Cargo.lock @@ -0,0 +1,7 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "commandtest" +version = "0.1.0" diff --git a/commandtest/src/main.rs b/commandtest/src/main.rs index 53aea2d..05efe91 100644 --- a/commandtest/src/main.rs +++ b/commandtest/src/main.rs @@ -1,5 +1,6 @@ use std::ffi::OsString; use std::fs::File; +use std::io::{BufRead, BufReader, Write}; use std::path::PathBuf; use std::process::Command; @@ -18,15 +19,41 @@ fn search_in_path(name: &str) -> Option { fn main() { // this requires always running with `cargo run` let base = PathBuf::from(env!("CARGO_MANIFEST_DIR")); - let log_file = File::create("script.log").unwrap(); let the_script = base.join("src").join("the_script.sh"); let bash = search_in_path("bash").unwrap(); let mut cmd = Command::new(bash) .arg(the_script) - .stdout(log_file) + .stdout(std::process::Stdio::piped()) .spawn() .unwrap(); + let stdout = cmd.stdout.take().unwrap(); + let writer_pid = std::thread::spawn(move || { + let reader = BufReader::new(stdout); + let lines = reader.lines(); + let mut log_file = File::create("script.log").unwrap(); + let mut in_warning = false; + let mut result = Vec::new(); + + for line in lines { + let line = line.unwrap(); + log_file.write(line.as_bytes()).unwrap(); + log_file.write(b"\n").unwrap(); // 'cause lines() eat it + + if line.starts_with("WARNING:") { + in_warning = true; + } else if line.starts_with(" ") && in_warning { + result.push(line); + } else if in_warning { + in_warning = false; + } + } + + result + }); + cmd.wait().unwrap(); + let warnings = writer_pid.join().unwrap(); + println!("Warnings:\n{:?}", warnings); } diff --git a/commandtest/src/the_script.sh b/commandtest/src/the_script.sh index ff7d534..8455da2 100755 --- a/commandtest/src/the_script.sh +++ b/commandtest/src/the_script.sh @@ -1,11 +1,19 @@ #!/usr/bin/env bash -echo "Hello, I'm a script!" -echo "I write stuff in the output." -echo "Everything should go to a file." -echo "But also, you need to capture this:" -echo "WARNING: This is a warning" -echo " It continues if the line starts with spaces" -echo " And keeps going till there are no more spaces-prefixes" -echo "Like this." -echo "Then you're good to go." +for loop in {1..1000} +do + echo "Hello, I'm a script!" + echo "I write stuff in the output." + echo "Everything should go to a file." + echo "But also, you need to capture warnings:" + + if (( $loop%7 == 0)); then + echo "WARNING: This is a warning" + echo " It continues if the line starts with spaces" + echo " And keeps going till there are no more spaces-prefixes" + fi + + echo "Like this." + echo "Then you're good to go." + echo "" +done