Perl цикл foreach печатает только одну строку - PullRequest
5 голосов
/ 24 января 2012

У меня есть этот Perl-код, который печатает только первую строку вместо всех строк.

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";
}

Он печатает:

/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

Я ожидаю:

/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

Я почти уверен, что это что-то базовое.Любая помощь приветствуется.Спасибо!

1 Ответ

16 голосов
/ 24 января 2012

Проблема в этой строке:

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";

Вы используете только первые несколько значений разбиения, но остальная часть этой строки также там.Другими словами, @values содержит все ожидаемые значения.Диапазон 0..5 содержит первую строку, 6..10 - следующую и т. Д.Так как вы используете только первые 6 значений, вы их не видите.

Быстрое решение может быть сделано:

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

Что могло бы сломать ваш ввод, как вы ожидалиэто будет.

Несколько советов:

Всегда use warnings; use strict;

И вы должны использовать некоторые надлежащие функции 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];
}

Itпохоже, что вы хотите напечатать строки MBsize ... после обычного вывода.Если это так, вы можете просто сохранить строки в массиве и напечатать после цикла:

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;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...