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.

Ejecutar strace con un -o (redirigir la salida de seguimiento) parsea la salida de seguimiento mientras imprime el stdout.

Estoy tratando de ejecutar algunos comandos strace de la siguiente manera:

my @cmd = shell_quote(@ARGV);

strace -f -o trace.log -e trace=file @cmd

Quiero revisar el archivo trace.log y analizarlo mientras se está ejecutando, también quiero imprimir el stdout de @cmd en la pantalla.

¿Alguna idea de cómo debería hacer eso … AYUDA 🙂

“`
sub shell_unquote {

my @strings = (@_);
my $arg;
for my $arg (@strings) {
if(not defined $arg) {
$arg = “”;
}
$arg =~ s/’\n’/\n/g; # los nombres de archivo con ‘\n’ se citan usando ‘\n’
$arg =~ s/\([\002-\011\013-\032])/$1/g;
$arg =~ s/\([#\?`(){}*>>~|\; \”!\$\&’])/$1/g;
$arg =~ s/\\/\/g;
}
return wantarray ? @strings : “@strings”;
}

Tags:  ,

Answer

  1. Avatar for davy.ai

    Para lograr esto, puedes usar una combinación de lectura de archivos e impresión en la salida estándar en tu script de Perl.

    En primer lugar, necesitas abrir el archivo trace.log para leer mientras se ejecuta el comando strace. Puedes usar la función incorporada de Perl open para este propósito:

    # abrir el archivo trace.log para lectura
    open(my $trace_fh, '<', 'trace.log') or die "No se pudo abrir trace.log: $!";
    

    Una vez que el archivo esté abierto, puedes usar un bucle para leer cada línea del archivo a medida que se escribe por el comando de strace:

    while(my $line = <$trace_fh>) {
        # procesar la línea
    }
    

    Dentro del bucle, puedes analizar cada línea de la salida utilizando expresiones regulares u otras técnicas de manipulación de cadenas. Por ejemplo, es posible que desees extraer el nombre de archivo al que accedió el comando. Podrías usar una expresión regular como esta:

    if($line =~ /^execve.*?\[(.*?)\].*$/) {
        my $filename = $1;
        # hacer algo con $filename
    }
    

    En este ejemplo, la expresión regular coincide con las líneas que comienzan con “execve”, seguido de una ruta de archivo entre corchetes. Los paréntesis capturan la ruta de archivo como un grupo, que luego se asigna a la variable $filename.

    Finalmente, para imprimir la salida @cmd en la pantalla, puedes usar la función incorporada de Perl print:

    # imprimir la salida @cmd en la pantalla
    open(my $cmd_fh, '-|', @cmd) or die "No se pudo ejecutar el comando: $!";
    while(my $line = <$cmd_fh>) {
        print $line;
    }
    close $cmd_fh;
    

    Este código utiliza la función open nuevamente, pero esta vez con la opción -|, que ejecuta la matriz @cmd como un comando y canaliza su salida al script de Perl. Luego, la salida se lee línea por línea e imprime en STDOUT utilizando la función print.

    Poniéndolo todo junto, tu script de Perl podría verse algo como esto:

    use strict;
    use warnings;
    use Shell::Quote;
    
    # construir matriz de comandos
    my @cmd = shell_quote(@ARGV);
    
    # abrir el archivo trace.log para lectura
    open(my $trace_fh, '<', 'trace.log') or die "No se pudo abrir trace.log: $!";
    
    # imprimir la salida @cmd en la pantalla
    open(my $cmd_fh, '-|', @cmd) or die "No se pudo ejecutar el comando: $!";
    while(my $line = <$cmd_fh>) {
        print STDOUT $line;
    }
    close $cmd_fh;
    
    # procesar la salida de trace.log
    while(my $line = <$trace_fh>) {
        if($line =~ /^execve.*?\[(.*?)\].*$/) {
            my $filename = $1;
            # hacer algo con $filename
        }
    }
    close $trace_fh;
    

    Este script debe ejecutar la matriz @cmd, imprimiendo su salida en la pantalla, mientras también monitorea los accesos a archivos y otras llamadas al sistema realizadas por el comando en trace.log. Puedes agregar código adicional dentro del bucle while para analizar y procesar llamadas al sistema específicas según sea necesario.

Comments are closed.