2012-01-24 8 views
5

Tengo este código Perl que solo imprime la primera línea en lugar de todas las líneas.Perl foreach loop imprime solo una línea

use Net::SSH::Perl; 
my $user = "user"; 
my $cmd = "df -m | grep data"; 
my $host = "host1.example.com"; 

my $ssh = Net::SSH::Perl->new($host); 
$ssh->login($user); 
my ($dflines,$errors,$exit) = $ssh->cmd($cmd); 
foreach $line ($dflines) { 
    print "$line"; 
    my @values = split(' ',$line); 
    my ($MBsize, $MBused, $MBavail, $dir) = 
     ($values[1], $values[2], $values[3], $values[5]); 
    print "MBsize=$MBsize MBused=$MBused MBavail=$MBavail dir=$dir\n"; 
} 

Imprime:

/dev/sdb1    1407118 931813 403828 70% /data1 
/dev/sdc1    1407118 921739 413902 70% /data2 
/dev/sdd1    1407118 909408 426233 69% /data3 
/dev/sde1    1407118 918828 416813 69% /data4 
/dev/sdf1    1407118 922335 413306 70% /data5 
MBsize=1407118 MBused=931813 MBavail=403828 dir=/data1 

Yo esperaría:

/dev/sdb1    1407118 931813 403828 70% /data1 
/dev/sdc1    1407118 921739 413902 70% /data2 
/dev/sdd1    1407118 909408 426233 69% /data3 
/dev/sde1    1407118 918828 416813 69% /data4 
/dev/sdf1    1407118 922335 413306 70% /data5 
MBsize=1407118 MBused=931813 MBavail=403828 dir=/data1 
MBsize=1407118 MBused=921739 MBavail=413902 dir=/data2 
MBsize=1407118 MBused=909408 MBavail=426233 dir=/data3 
MBsize=1407118 MBused=918828 MBavail=416813 dir=/data4 
MBsize=1407118 MBused=922335 MBavail=413306 dir=/data5 

Estoy casi seguro de que es algo básico. Se agradece cualquier ayuda. Gracias!

+0

no se olvide: 'use strict; use advertencias; ' – Ether

Respuesta

16

El problema es esta línea:

foreach $line ($dflines) { 

Sólo se está ejecutando una iteración, ya que no es una matriz, pero un escalar. Cuando print "$line" imprime todas las líneas que capturó, creo que parece que imprimió muchos valores en un bucle. En la parte posterior:

my @values = split(' ',$line); 
my ($MBsize, $MBused, $MBavail, $dir) = 
     ($values[1], $values[2], $values[3], $values[5]); 
print "MBsize=$MBsize MBused=$MBused MBavail=$MBavail dir=$dir\n"; 

sólo utiliza los primeros valores de la división, pero el resto de la línea es de allí también. En otras palabras, @values contiene todos los valores que espera. El rango 0..5 contiene la primera fila, 6..10 el siguiente, y así sucesivamente. Como solo usa los primeros 6 valores, no los ve.

Una solución rápida podría ser la de hacer:

foreach $line (split /\n/, $dflines) { 

lo que podría romper su entrada de la manera que se esperaba que fuera.

Algunos consejos:

Siempre use warnings; use strict;

Y usted debe hacer uso de algunas de las características propias de Perl:

for my $line (split /\n/, $dflines) { 
    print $line; 
    my @values = split ' ', $line; 
    printf "MBsize=%s MBused=%s MBavail=%s dir=%s\n", @values[1,2,3,5]; 
} 

Parece que desea imprimir los MBsize ... líneas después de la salida normal. Si es así, puede simplemente almacenar las líneas en una matriz e imprimir después del ciclo:

my @print; 
for my $line (split /\n/, $dflines) { 
    print $line; 
    my @values = split ' ', $line; 
    push @print, sprintf "MBsize=%s MBused=%s MBavail=%s dir=%s\n", @values[1,2,3,5]; 
} # note ----^ sprintf instead 
print @print; 
+1

Gracias, TLP. Eso fue súper útil. Aprecio especialmente la información adicional mientras trato de mejorar en Perl. –

+1

@senile_genius De nada. – TLP

Cuestiones relacionadas