Hay dos fallos: la función system() no sirve para lo que quieres. Esta función es cierto que ejecuta un comando en el sistema, pero no devuelve el resultado de la ejecución (la salida estándar), sino el ESTADO del resultado de la ejecución. Es decir, devolverá un 0 o un 1 según el último comando se ejecutó sin problemas u ocurrió un error.
Como lo que quieres es obtener la salida (estándar) del resultado de una serie de comandos en línea, debes usar las comillas inversas (``) o qx().
Ahora bien... ¿por qué no te funciona cuando usas qx()? Ahora viene el segundo fallo.
Resulta que qx() es un comando "de entrecomillado". Quiere decir que lo que pongamos dentro de los paréntesis será interpolado por Perl ANTES de pasarse al sistema. Una interpolación igual a la que ocurre con comillas dobles.
Y ahí está el problema: en tus comandos hay cosas como
$1 o
$NF. Y para Perl, esas cosas son variables escalares, así que las interpolará -sacará su valor como si fueran variables Perl y pondrá ese valor en la línea de comandos.
Pero eso no son variables para Perl. Son variables para el shell o para el awk. Así que hay que evitar que Perl las reconozca.
La solución es "escapar" el significado de los '$', para que pasen directamente a la línea de comandos que se ejecutará por el sistema:
Using perl Syntax Highlighting
#!/usr/bin/env perl
my $comando = qx(grep 'for .*@.*' /var/log/exim4/mainlog | grep '<= <>' | awk '{print \$NF, \$0}' | awk -F ' for' '{print \$1}' | sort | uniq -c | sort -n);
my $comando2 = qx(exim -bpr | grep "<" | awk {'print \$4'} | cut -d "<" -f 2 | cut -d ">" -f 1 | sort -n | uniq -c | sort -n);
my $comando3 = qx(exim -bpr | exiqsumm -c | head | awk '{print \$1,\$2}');
print $comando . "\n";
print $comando2 . "\n";
print $comando3 . "\n";
Coloreado en 0.001 segundos, usando
GeSHi 1.0.8.4
O... también... hay otra forma...
Usar las comillas simples como delimitadores de qx()... pero entonces no podemos usar comillas simples en la línea de comandos:
Using perl Syntax Highlighting
my $comando = qx'comando $1 $2 $3'; # $1, $2 y $3 son variables del shell. No son variables Perl
Coloreado en 0.001 segundos, usando
GeSHi 1.0.8.4
(Más información en perldoc perlop, sección
Quote-Like Operators).
Ahora bien... ¿Por qué tanto lío? ¿No es mejor resolver este problema solo con Perl? Nuestro lenguaje favorito es capaz de hacer todo eso, de forma más independiente del sistema (no necesitas que en tu sistema estén instalados los comandos sort, uniq, cut, head, grep y awk).
¿Qué es lo que hace este programa? Sacar estadísticas de actividad del sistema de correo electrónico.
Using perl Syntax Highlighting
#!/usr/bin/env perl
use v5.14;
use autodie;
## Listado de mensajes rebotados
my $archivo_log = '/var/log/exim4/mainlog';
my %emails;
open my $LOG, '<', $archivo_log;
while (<$LOG>) {
next if not /<= <>/;
next if not / for (\S+)/;
$emails{ $1 }++;
}
close $LOG;
for my $email ( sort { $emails{$a} <=> $emails{$b} } keys %emails ) {
say "$emails{$email}\t$email";
}
## Remitentes con mensajes pendientes de entrega
my %pendientes;
open my $PENDIENTES, 'exim4 -bpr|';
while (<$PENDIENTES>) {
next if not /<(.*?)>/;
$pendientes{ $1 }++;
}
close $PENDIENTES;
for my $pend ( sort { $pendientes{$a} <=> $pendientes{$b} } keys %pendientes ) {
say "$pendientes{$pend}\t$pend";
}
## Tamaño de los mensajes pendientes de entrega
my %size;
open my $SIZE, 'exim4 -bpr| exiqsumm -c|';
while (<$SIZE>) {
my @campos = split;
say $campos[1] ;
}
close $SIZE;
Coloreado en 0.001 segundos, usando
GeSHi 1.0.8.4