extracting values from vmstat output

A

alfonsobaldaserra

hi list,

i'm trying to calculate memory pages on aix platform. the output of

$ vmstat -v is like
2031616 memory pages
1953185 lruable pages
935166 free pages
1 memory pools
170943 pinned pages
80.0 maxpin percentage
3.0 minperm percentage
90.0 maxperm percentage
6.8 numperm percentage
133573 file pages
0.0 compressed percentage
0 compressed pages
6.8 numclient percentage
90.0 maxclient percentage
133573 client pages
0 remote pageouts scheduled
81 pending disk I/Os blocked with no pbuf
0 paging space I/Os blocked with no psbuf
2484 filesystem I/Os blocked with no fsbuf
0 client filesystem I/Os blocked with no fsbuf
451 external pager filesystem I/Os blocked with no
fsbuf
0 Virtualized Partition Memory Page Faults
0.00 Time resolving virtualized partition memory page
faults

in perl code i'm storing this value into a variable

my @vmstat = system("vmstat -v");

now i want to extract the numerical values of memory pages and free
pages. what is the best possible way to do that?

thanks in advance
 
T

Tad J McClellan

alfonsobaldaserra said:
$ vmstat -v is like
2031616 memory pages
1953185 lruable pages
935166 free pages
1 memory pools
170943 pinned pages
80.0 maxpin percentage
3.0 minperm percentage
90.0 maxperm percentage
6.8 numperm percentage
133573 file pages
0.0 compressed percentage
0 compressed pages
6.8 numclient percentage
90.0 maxclient percentage
133573 client pages
0 remote pageouts scheduled
81 pending disk I/Os blocked with no pbuf
0 paging space I/Os blocked with no psbuf
2484 filesystem I/Os blocked with no fsbuf
0 client filesystem I/Os blocked with no fsbuf
451 external pager filesystem I/Os blocked with no
fsbuf
0 Virtualized Partition Memory Page Faults
0.00 Time resolving virtualized partition memory page
faults

in perl code i'm storing this value into a variable


No you're not. You are storing some other value into a one-element array.

my @vmstat = system("vmstat -v");


Have you examined the contents of @vmstat?

It does not contain what you think it contains...

You should read the documentation for the functions that you use:

perldoc -f system

now i want to extract the numerical values of memory pages and free
pages. what is the best possible way to do that?


# untested
my $vmstat = qx/vmstat -v/;
my($memory) = $vmstat =~ /(\d+) memory pages/;
my($free) = $vmstat =~ /(\d+) free pages/;
 
U

Uri Guttman

GB> no warnings "exec";

why is that needed?

GB> open my $fh, "vmstat -v |"
GB> or die "$0: can't execute vmstat: $!\n";

as you said a qx would work too and would be simpler. in a list context
it returns lines so you could do a for loop. i doubt it will generate
too many lines.

GB> %vmstat = reverse `vmstat -v` =~ /(\S+) (.+)/g;

that is how i would do it and i thought of the same code before i saw
yours. i do a very similar thing with file::slurp and parsing simple
config files. parsing a multiline string with m//g into a key/value list
and assigning directly to a hash is a great and underused idiom. it is
also much faster than looping over lines and parsing each one and
assigning into the hash.

uri
 
A

alfonsobaldaserra

    # untested
    my $vmstat = qx/vmstat -v/;
    my($memory) = $vmstat =~ /(\d+) memory pages/;
    my($free)   = $vmstat =~ /(\d+) free pages/;

your untested code turned out to be perfect. i got what i wanted.
thank you.

but i have one question could you please answer? why are you using
$memory and $free in list context? i tried running it as scalar and
the output was 1 but in list context it gives correct value.

greg your code worked very nice and thank you so much for the amazing
explanations.
 
T

Tim Greer

alfonsobaldaserra said:
your untested code turned out to be perfect. i got what i wanted.
thank you.

but i have one question could you please answer? why are you using
$memory and $free in list context? i tried running it as scalar and
the output was 1 but in list context it gives correct value.

greg your code worked very nice and thank you so much for the amazing
explanations.

One method is the result of the "test" of that condition (matching),
while the other assigns the value returned (not true or false). It's
not that it's in a list context, in other words, and you can see the
difference in how it's used in the results you've witnessed.
 
T

Tad J McClellan

[ attribution missing... ]

why are you using
$memory and $free in list context?


Because it DWIMs more clearly (IMO) than the alternatives.

What I Mean is usually:

set $memory to a capture if matched, set it to undef if unmatched.

That's what my list-context approach above does.

The good, but less clear and more wordy, approach to it is:

my $memory;
if ( $vmstat =~ /(\d+) memory pages/ ) {
$memory = $1;
}

or

my $memory;
$memory = $1 if $vmstat =~ /(\d+) memory pages/;


The construct I am specifically avoiding is:

my $memory = $1 if $vmstat =~ /(\d+) memory pages/;

to avoid the dragons referred to in the "Statement Modifiers"
section of perlsyn.pod:


B<NOTE:> The behaviour of a C<my> statement modified with a statement
modifier conditional or loop construct (e.g. C<my $x if ...>) is
B<undefined>. The value of the C<my> variable may be C<undef>, any
previously assigned value, or possibly anything else. Don't rely on
it. Future versions of perl might do something different from the
version of perl you try it out on. Here be dragons.
 
U

Uri Guttman

TJM> my $memory;
TJM> $memory = $1 if $vmstat =~ /(\d+) memory pages/;


TJM> The construct I am specifically avoiding is:

TJM> my $memory = $1 if $vmstat =~ /(\d+) memory pages/;

TJM> to avoid the dragons referred to in the "Statement Modifiers"
TJM> section of perlsyn.pod:

so use the conditional expression:

my $memory = $vmstat =~ /(\d+) memory pages/ ? $1 : undef ;

but the list context method is fine IMO.

and i still prefer the grabbing of all the values into a hash in one
statement. declaring a lexical for each of many values is bad news. we
just had a thread on someone who did that (not parsed out, just declared
too many vars).

uri
 
T

Tim Greer

Sherm said:
Context is *exactly* what makes that difference. In scalar context,
the =~ operator returns true/false, and in list context it returns a
list of the matched subexpressions.

See 'perldoc perlop' and 'perldoc perlre' for details.

sherm--

You cut out the part that said "in other words". I meant that it's not
just the list context, but how it's used (the behavior in list context)
and that it depends on the particular operator (just like the docs
say)... just like the OP observed and just like I said above (returning
true or false, or the return value, depending). In "other words", they
needed to know that if it didn't capture the desired value in
parethesis on the right, it would give them a different result, too.
Perhaps it was poorly explained by not elaborating on what I meant, but
it was not a disagreement with anything you've said above or in the
docs themselves.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,744
Messages
2,569,482
Members
44,901
Latest member
Noble71S45

Latest Threads

Top