Perl Programming


HOME HTML Tree Enhancing vi Graphical df Search Subdirs Super Sorts

INDEX

HOME
Content...
About this site...
HTML Tree
Super Sorts
Graphical df
Enhancing vi
Search Subdirs

Finding CPU Hogging Processes


The following script is a quick one-off, but a useful way to find out which processes are currently loading down your system for those who don't have access to top. The script parses the output of the ps -elf command looking for CPU hogs, and displays it in an easy to read format. It is therefore limited to Unixes that have System V compatible "ps" parameters (e.g. HPUX, Solaris).

I call it "hogs.pl", the poor man's top. The script starts by reading the output of uptime in order to present the current system load values. It then parses the output from ps to find out which processes are registering a CPU load (the sixth column of output).


        #!/usr/bin/perl
        #
        # Script to list system hogs to std output
        #
        # print the uptime line first 
        print "---------------------------------------------------------------\n";

        # open a handle for "uptime" with a receive pipe
        $pid = open( PSHANDLE, "/usr/bin/uptime |" );
        while ()
        {
            print;
        }
        close( PSHANDLE );

        # format a header for the process table
        print "---------------------------------------------------------------\n";
        print "load\tuser\tsize\tprocess\tprocess name\n";
        print "---------------------------------------------------------------\n";

        # open a handle for the output from "ps"
        $pid = open( PSHANDLE, "/bin/ps -elf |" );

        # print the hoggy processes next
        while ()
        {
            chop;
            ps_fields = split( ' ', $_ );
            # if CPU load is indicated, print the entry
            if ( $ps_fields[5] != 0 )
            {
                print "$ps_fields[5]\t$ps_fields[2]\t$ps_fields[9]\t$ps_fields[3]";
                print  "\t$ps_fields[13] $ps_fields[14] $ps_fields[15] $ps_fields[16] $ps_fields[17] \n";
            }
        }
        close( PSHANDLE );
        print "---------------------------------------------------------------\n";
        # the end.

Example Output

        ---------------------------------------------------------------
          3:49pm  up 25 days, 21:42,  9 users,  load average: 1.30, 1.30, 1.36
        ---------------------------------------------------------------
        load    user    size    process process name
        ---------------------------------------------------------------
        8       root    252     676     ? 334:03 /usr/perf/bin/scopeux
        2       alexops 0       23592   0:00 ksh -c DISPLAY=XX.XX.XX.XX:0.0;expo
        17      src     127     26676   0:00 /usr/local/bin/perl
        14      src     18      26678   /bin/ps -elf
        121     daemon  1204    25716   472:38 oraclerrs T:I,4096,5
        13      alexbku 1168    1874    ttyv6 6:20 Xalex -q
        121     daemon  1123    21159   oraclerrs T:I,4096,5
        2       alexops 0       14530   ksh -c DISPLAY=XX.XX.XX.XX:0.0;expo
        ---------------------------------------------------------------

If your perl binary is not in /usr/bin/perl, you'll need to update the first comment line and the first two lines of code to the correct location. The easiest way to use the script is to cut it from your browser and paste it into an editor's buffer. Remember to use "chmod +x" to make the script executable.

This script is useful in how it demonstrates a means of collecting the output of a multi-line system command and parsing it to show just the data that interests us. It also shows how to convert a line of output into an array using "split", to make comparing specific information convenient.

The reason this script has some rough edges is that the process name is the last entry in the output from "ps" on each line, and the number of items printed on each line varies slightly. This makes counting across to find the process name uncertain. The script uses the shotgun approach by printing five entries under the "process name" header, starting with the first element that could potentially be the process name.

Another more excusable sin is that there will always be two entries shown which could be filtered - the "ps" and "perl" commands. This is a feature of most system load monitoring programs.


The above text and scripts are Copyright 2000 © by Scott Chilcote.

HOME HTML Tree Enhancing vi Super Sorts Search Subdirs CPU Hogs