I have this Perl code that is only printing the first line instead of all the lines.
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";
}
It prints:
/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
I would expect:
/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
I'm almost certain it's something basic. Any help is appreciated. Thanks!
There is no difference. From perldoc perlsyn: The foreach keyword is actually a synonym for the for keyword, so you can use foreach for readability or for for brevity. Save this answer.
A foreach loop is used to iterate over a list and the variable holds the value of the elements of the list one at a time. It is majorly used when we have a set of data in a list and we want to iterate over the elements of the list instead of iterating over its range.
In many programming languages you use the break operator to break out of a loop like this, but in Perl you use the last operator to break out of a loop, like this: last; While using the Perl last operator instead of the usual break operator seems a little unusual, it can make for some readable code, as we'll see next.
The problem is this line:
foreach $line ($dflines) {
You are only executing one iteration, since that is not an array, but a scalar. When you print "$line"
it actually prints all of the lines that you captured, but I guess it looks like you printed many values in a loop. In the subsequent part:
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";
You only use the first few values of the split, but the rest of that line is in there as well. In other words, @values
contains all of the values you expect. Range 0..5 contains the first row, 6..10 the next, and so on. Since you only use the first 6 values, you don't see them.
A quick fix might be to do:
foreach $line (split /\n/, $dflines) {
Which would break up your input the way you were expecting it to be.
Some tips:
Always use warnings; use strict;
And you should make use of some proper perl features:
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 looks like you want to print the MBsize ...
lines after the regular output. If so, you can just store the lines in an array and print after the loop:
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;
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With