diff --git a/src/main.rs b/src/main.rs index de111c3..5e1eb92 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,33 +1,90 @@ use std::env; -use std::io::{self, Write}; -use std::process::Command; +use std::io::{BufRead, BufReader}; +use std::process::{Command, Stdio}; +use std::sync::mpsc; +use std::thread; +use std::time::Duration; -fn retry(cmd: &String, cmd_args: &[String]) { +fn read_stream(stream: &mut mpsc::Receiver, output: &mut Vec) { loop { - let output = Command::new(cmd) - .args(cmd_args) - .output() - .map_err(|e| { - eprintln!("Failed to execute command: {}", e); - io::stderr().flush().unwrap(); - }); - - match output { - Ok(output) => { - io::stdout().write_all(&output.stdout).unwrap(); - if output.status.success() { - break; - } - - eprintln!("Command failed with status: {}", output.status); - println!("{}", String::from_utf8_lossy(&output.stderr)); + match stream.try_recv() { + Ok(line) => { + output.push(line); } - Err(_) => { - println!("Error, wait 1s for retry.") + Err(mpsc::TryRecvError::Disconnected) => { + break; + } + Err(mpsc::TryRecvError::Empty) => { + thread::sleep(Duration::from_millis(100)); + } + } + } +} + +fn retry(cmd: &str, cmd_args: &[String]) { + loop { + let (stdout_sender, mut stdout_receiver) = mpsc::channel(); + let (stderr_sender, stderr_receiver) = mpsc::channel(); + + let mut child = Command::new(cmd) + .args(cmd_args) + .stdout(Stdio::piped()) + .stderr(Stdio::piped()) + .spawn() + .expect("Failed to spawn command"); + + let status = child.wait().expect("Failed to wait for command"); + + if status.success() { + let stdout_vec: Vec = { + let stdout_handle = thread::spawn(move || { + let reader = BufReader::new(child.stdout.take().unwrap()); + for line in reader.lines() { + let line = line.expect("Failed to read line from stdout"); + stdout_sender.send(line).expect("Failed to send stdout line"); + } + }); + + stdout_handle.join().unwrap(); + stdout_receiver.try_iter().collect() + }; + + println!("Command succeeded."); + for line in stdout_vec { + println!("stdout: {}", line); + } + + break; + } else { + let stderr_vec: Vec = { + let stderr_handle = thread::spawn(move || { + let reader = BufReader::new(child.stderr.take().unwrap()); + let mut lines = Vec::new(); + for line_result in reader.lines() { + if let Ok(line) = line_result { + // 克隆line后发送 + stderr_sender.send(line.clone()).expect("Failed to send stderr line"); + lines.push(line); + } else { + eprintln!("Error reading stderr line: {:?}", line_result); + } + } + lines + }); + + stderr_handle.join().unwrap(); + stderr_receiver.try_iter().collect() + }; + eprintln!("Command failed with status: {}", status); + for line in stderr_vec { + eprintln!("stderr: {}", line); } } - std::thread::sleep(std::time::Duration::from_secs(1)); + let mut stdout_output: Vec = Vec::new(); + read_stream(&mut stdout_receiver, &mut stdout_output); + + thread::sleep(Duration::from_secs(1)); } }