Alien has asked for the wisdom of the Perl Monks concerning the following question:

Hi !

How could the output of the top program ( and programs similar to it ) could be captured in a script ?

I tried using $var=`top` , and even opened it with a pipe , it can read the first screen but no more than that.

Thanks!

Replies are listed 'Best First'.
Re: Capturing top-like program output
by Util (Priest) on Jan 06, 2007 at 18:44 UTC
    while (1) { my $top_output = `top -l 1`; do_something_with( $top_output ); sleep 5; }
    From `man top`:
    -l <samples>
    Use logging mode and display <samples> samples, even if standard output is a terminal. 0 is treated as infinity. Rather than redisplaying, output is periodically printed in raw form.
Re: Capturing top-like program output
by dorko (Prior) on Jan 06, 2007 at 18:51 UTC
    Try taking a look at the man pages for top. If you open it in batch mode (-b) with a single iteration (-n 1), I'm guessing you could capture the output of a single update from top. Process that output, save it, display it or whatever you wanted to do with it, then fetch another screen of output.

    Completely untested:

    my $n = 1; while( $n < 5 ) { # capture a single screen's worth of output... my $temp = `top -b -n 1`; # process $temp here... # play nice sleep 15; $n = $n + 1; }

    Cheers,

    Brent

    -- Yeah, I'm a Delt.

      I realize that that -b switch is the simplest answer to Alien's question, but personally, I still wonder how you would capture raw console writes from perl.

      -Paul

        Me too :)
Re: Capturing top-like program output
by zentara (Cardinal) on Jan 06, 2007 at 20:35 UTC
    There are a few ways of dealing with top, this one works pretty well.
    #!/usr/bin/perl use warnings; use strict; use IPC::Open3; use IO::Select; my $pid = $$; my $pid1 = open3(0, \*READ,\*ERROR,"top -d 1 -b -p $pid "); #if \*ERROR is false, STDERR is sent to STDOUT my $sel = new IO::Select(); $sel->add(\*READ); $sel->add(\*ERROR); my($error,$answer)=('',''); while(1){ foreach my $h ($sel->can_read){ my $buf = ''; if ($h eq \*ERROR){ sysread(ERROR,$buf,4096); if($buf){print "ERROR-> $buf\n"} }else{ sysread(READ,$buf,4096); if($buf){print "$buf\n"} } } }

    I'm not really a human, but I play one on earth. Cogito ergo sum a bum