TechRepublic
asked members to submit their favorite Network Administration scripts for
possible publication. One of the latest to make a submission was Chad Perrin. This contribution to
TechRepublic earned apotheon $100 and the
satisfaction derived from seeing those scripts published.


Earn $100 for your admin script

Let us
pay you for your original scripts so that we can publish them as downloads on
TechRepublic and allow your fellow IT professionals to benefit from your
scripting savvy. We only ask that you put in the appropriate comments to your
scripts so that it’s easy to tell what the script is doing and which variables
might need to be customized. Send us your original
admin scripts
and we’ll pay you $100
for each one that we publish as a TechRepublic download.


Editor’s note: This script is included in the downloadable Zip
file for your convenience.

In their own words

I’ve
commented the heck out of a Perl script called killp
that was written to provide a convenient way to kill processes by name rather
than by number.  Rather than write a
separate explanation of the script or embed the script’s text in a larger
article, I decided to stick the introductory explanation into the script itself
as comments.  Hopefully this works out
for your needs.

The
script is attached as a file called killp.pl (the .pl extension is for Perl
scripts, but the file itself is simply text format) in UNIX format for ease of
use by Linux admins and again as a file called
killp.txt in DOS/Windows format for ease of viewing and editing in a Windows
environment.

Listing A (Perl/UNIX version)

#!/usr/bin/perl -w

# Sometimes, you just want to be able to kill a process with
# only one command, so that you don’t have to look up the
# process ID number (PID) of a given process yourself.  This
# script provides that functionality, and attempts to target
# the parent process with the process name you specify.  It’s
# best to be aware of the way it works before using it so
# that you do not accidentally kill the wrong process, and
# because of this extensive comments have been added to the
# source code.
#
# This is a Perl script written for use on any unixlike OS
# that supports the GNU ps command.  It is saved on the
# author’s system as killp.pl, and symlinked as ~/bin/killp
# for ease of use.

# include strict pragma and option handling module
use strict;
use Getopt::Std;

# declare help variable and create help option text
my $help = ‘
The killp (for “kill process”) utility is designed to
allow the system administrator to kill a process on a
machine quickly using its process name.  Simply put, you
use it to kill the lowest-PID process whose “ps -ef”
output contains a specified string.

syntax:
        killp [-v] [-n <string>]
        killp [-h]

-v
        verbose: This gives verbose output.

-n <string>
        This is used to specify the process you wish to
        kill.  If multiple processes match this string,
        the one with the lowest PID will be killed, with
        the intent that the parent process of a family of
        processes with the same name can be killed
        quickly.

-h
        This will cause killp to print this help message,
      as will simply omitting the -n option.

credits:        Chad L. Perrin (author)

license:  This utility is released under terms of the
CCD CopyWrite.  See the following URL for details:

        http://ccd.apotheon.org

‘;

# declare variables using lexical scope
our
(
  $a, $b, $opt_h, $opt_n, $opt_v,
  @pids, @target
);

# populate option variables
getopts(‘n:vh’);

# main program logic
if (defined $opt_h)         # help option conditional
{
  print $help;
  exit;
} elsif (defined $opt_n) {  # process name option conditional
  target_list($opt_n);
  pid_list(@target);
  @pids = sort {$a cmp $b} @pids;
  kill_top_pid(@pids);
} else {                    # no options conditional
  print $help;
  exit;
}

###########################
# subroutines (functions) #
###########################
sub target_list
# This subroutine opens a ps command, reads its output, and
# creates an array called @target that is populated with all
# ps output lines that contain the process name specified by
# the -n option for this script.
{
  open(PS,”ps -ef |”);
  foreach (<PS>)
  {
    chop($_);
    push(@target,$_) if ($_ =~ /$opt_n/);
  }
  close PS;
}

sub pid_list
# This subroutine takes the list of processes in @target as
# its argument and splits each line of process data to
# make the PIDs (process ID numbers) of each process in the
# list accessible, then uses the relevant strings to
# populate the @pids array.
{
  foreach (@_)
  {
    my @proc = split /\s+/, $_, 2;
    push(@pids,$proc[1]);
  }
}

sub print_iterate
# This subroutine is used to print process data to STDOUT
# when the -v option is specified for this script.
{
  foreach (@_)
  {
    print;
    print “\n”;
  }
}

sub kill_top_pid
# This subroutine does the actual work of checking for a
# red herring and killing the lowest PID number that
# matches the process name fed to this script by its -n
# option.  The red herring check is used to determine
# whether the lowest PID that matches is actually the PID
# of this script, since it too will match the -n option
# input string.  This subroutine also prints process
# information to STDOUT if the -v option is used.
{
  my @proc = split /\s+/, $pids[0];

  if ($pids[0] =~ /$$/)
  {
    print (“no such process found\n”);
  } elsif ($pids[0] =~ /$opt_n/) {
    kill(‘TERM’, $proc[0]);
    if ($opt_v)
    {
      print_iterate(@pids);
      die (“victim:  ” . $pids[0] . “\n”);
    }
  }
}