Browse Source

Spawn a thread to capture and process the output

master
Julio Biason 1 year ago
parent
commit
9eef6fcafa
  1. 7
      commandtest/Cargo.lock
  2. 31
      commandtest/src/main.rs
  3. 26
      commandtest/src/the_script.sh

7
commandtest/Cargo.lock generated

@ -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"

31
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<PathBuf> {
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);
}

26
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

Loading…
Cancel
Save