1234567890Richard:

On Mon, May 18, 2015 at 12:27 PM, Richard Taubo <o...@bergersen.no> wrote:
> Hi,

Hello,

> The full (bash) script with perl parts looks like this:
> [$] top_return=$(top -n1 | head -5)
> [$] io_return=$(printf "%s\n" "$top_return" | grep "^Cpu(s)")
> [$] io_all=$(printf  "%s" "$io_return" | awk '{ printf $9 }' | perl -pe 
> 's/\%st//')
> [$] printf "%s\n" "$io_all"

Since you're using Perl here I wonder why you're bothering with bash
and shell commands. Since the output of those commands will vary by
system (I can't be sure what you're trying based on my results) it's
impossible for us to debug your problem. However, we can demonstrate a
more straightforward, Perl-only solution using output from our own
system.

use autodie;
use strict;
use warnings;

use Data::Dumper;

$Data::Dumper::Useqq = 1;

main();
exit(0);

sub main {
    # On my system top outputs control characters for colors and such.
    # This is a simple way to convince it to do nothing special.
    my $term = $ENV{TERM};

    $ENV{TERM} = 'dumb';

    my $cpu_stats = parse_cpu_stats();

    $ENV{TERM} = $term;

    print Dumper $cpu_stats;
}

sub parse_cpu_stats {
    # Use a pipe to top(1) to read the output directly.
    open my $fh, '-|', qw/top -n1/;

    while (my $line = <$fh>) {
        chomp($line);

        # Look for the Cpu line.
        if ($line =~ /Cpu/) {
            return parse_pairs($line);
        }
    }
}

sub parse_pairs {
    my ($line) = @_;

    # Results in (0.5, 'us', 0.1, 'sy', 0.0, 'ni', 99.1, 'id',
    #             0.3, 'wa', 0.0, 'hi', 0.0, 'si', 0.0, 'st');
    my @pairs = $line =~ /([0-9]+\.[0-9]+)\s+(..)/gi;

    # Results in (us => 0.5, sy => 0.1 ni => 99.1 id => 0.3,
    #             hi => 0.0, si => 0.0, st => 0.0)
    my %fields = reverse @pairs;

    return \%fields;
}

__END__

This was hacked against the Debian Linux top(1) implementation.
Example output is:

> %Cpu(s):  0.5 us,  0.1 sy,  0.0 ni, 99.1 id,  0.3 wa,  0.0 hi,  0.0 si,  0.0 
> st

Output from the above program is:

$VAR1 = {
          "wa" => "0.3",
          "hi" => "0.0",
          "ni" => "0.0",
          "st" => "0.0",
          "us" => "0.5",
          "id" => "99.1",
          "si" => "0.0",
          "sy" => "0.1"
        };

I'm not saying this is a better or more robust solution than hacking
it up in bash, but at least by using Perl you have the full power of
Perl without switching between bash, grep, awk, and perl.

The Interwebz suggests that checking /proc would be a better solution,
though that would vary by the *nix system. In general, you should
prefer CPAN modules for this since the solution is flaky, and
hopefully somebody else has already done any heavy lifting and ugly
work for you... I didn't immediately see a module that looked like a
drop-in replacement, but I would be surprised if nothing exists yet.

Regards,


-- 
Brandon McCaig <bamcc...@gmail.com> <bamcc...@castopulence.org>
Castopulence Software <https://www.castopulence.org/>
Blog <http://www.bambams.ca/>
perl -E '$_=q{V zrna gur orfg jvgu jung V fnl. }.
q{Vg qbrfa'\''g nyjnlf fbhaq gung jnl.};
tr/A-Ma-mN-Zn-z/N-Zn-zA-Ma-m/;say'

-- 
To unsubscribe, e-mail: beginners-unsubscr...@perl.org
For additional commands, e-mail: beginners-h...@perl.org
http://learn.perl.org/


Reply via email to