test stream output.
This commit is contained in:
		
							
								
								
									
										103
									
								
								src/main.rs
									
									
									
									
									
								
							
							
						
						
									
										103
									
								
								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<String>, output: &mut Vec<String>) {
 | 
			
		||||
    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<String> = {
 | 
			
		||||
                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<String> = {
 | 
			
		||||
                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<String> = Vec::new();
 | 
			
		||||
        read_stream(&mut stdout_receiver, &mut stdout_output);
 | 
			
		||||
 | 
			
		||||
        thread::sleep(Duration::from_secs(1));
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user