es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

¿Cómo guardar la salida del comando en un archivo?

Estoy escribiendo una función que tiene un requisito de registro particular. Quiero capturar la salida de una llamada a <code>Command::new()</code> y guardarla en un archivo. Aquí simplemente estoy usando echo para facilitar las cosas.

fn sys_command(id: &str) -> u64 {
    let mut cmd = Command::new("echo")
        .args(&[id])
        .stdout(Stdio::piped())
        .spawn()
        .expect("fallo en el echo");

    let stdout = cmd.stdout.as_mut().unwrap();
    let stdout_reader = BufReader::new(stdout);
    // let log_name = format!("./tmp/log/{}.log", id);
    // fs::write(log_name, &stdout_reader);
    println!("{:?}", stdout_reader.buffer());

    cmd.wait().expect("fallo en la llamada");
    id.parse::<u64>().unwrap()
}

¿Cómo puedo capturar la salida y guardarla en un archivo? He creado un ejemplo en el playground. Mi llamada a println! devuelve [].

Incluso leyendo en otro buffer se imprime el valor incorrecto. A continuación, sys_command("10") imprime 3. Aquí tienes un ejemplo actualizado.

fn sys_command(id: &str) -> u64 {
    let mut buffer = String::new();
    let mut cmd = Command::new("echo")
        .args(&[id])
        .stdout(Stdio::piped())
        .spawn()
        .expect("fallo en el echo");

    let stdout = cmd.stdout.as_mut().unwrap();
    let mut stdout_reader = BufReader::new(stdout);
    let result = stdout_reader.read_to_string(&mut buffer);
    println!("{:?}", result.unwrap());

    cmd.wait().expect("fallo en el dibujo");
    id.parse::<u64>().unwrap()
}

¿Qué me falta?

Tags:  , ,

Answer

  1. Avatar for davy.ai

    Para capturar la salida y guardarla en un archivo, puedes utilizar las funciones File y write_all del módulo std::fs. Aquí tienes un ejemplo de implementación:

    use std::fs::{self, File};
    use std::io::{BufRead, BufReader, Write};
    use std::process::{Command, Stdio};
    
    fn sys_command(id: &str) -> u64 {
        let log_name = format!("./tmp/log/{}.log", id);
        let mut file = File::create(&log_name).expect("fallo al crear el archivo de registro");
    
        let mut cmd = Command::new("echo")
            .args(&[id])
            .stdout(Stdio::piped())
            .spawn()
            .expect("fallo al ejecutar el comando echo");
    
        let stdout = cmd.stdout.as_mut().unwrap();
        let stdout_reader = BufReader::new(stdout);
        for line in stdout_reader.lines() {
            let line = line.unwrap();
            println!("{}", line);
            file.write_all(line.as_bytes()).expect("fallo al escribir en el archivo");
        }
    
        cmd.wait().expect("fallo al esperar la finalización del comando");
        id.parse().unwrap()
    }
    

    Aquí, creamos un objeto File utilizando el nombre del archivo de registro deseado, y luego utilizamos un bucle for para iterar sobre las líneas de salida de la llamada al comando Command. Imprimimos cada línea en la consola y también la escribimos en el archivo utilizando el método write_all.

    Ten en cuenta que si la salida contiene bytes no UTF-8, es posible que debas ajustar el código de escritura en el archivo en consecuencia.

Comments are closed.