Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl Monk, Perl Meditation

by Falkkin (Chaplain)
on Dec 25, 2000 at 00:30 UTC ( [id://48206] : sourcecode . print w/replies, xml ) Need Help??
Category: GUI Programming
Author/Contact Info Colin McMillen (
Description: is a graphical process-management program. It uses the Tk module for GUI and currently delegates to the system's "ps" and "kill" commands for actual process management. It supports the signals TERM, STOP, CONT, INT, HUP, and KILL (if your system supports them all.)

In its current configuration, it runs on my Debian GNU/Linux box; others may have to tweak it slightly to get it to work on their machines. Check the source for more info. If there is any demand for a more portable version of this program, I'll work on it.

The latest version of this program, along with a screenshot and other information, will always be available at

Update: somehow, the code I had posted here didn't make it to the page; I've re-added the code, so go ahead and take a look at it.

#!/usr/bin/perl -w

# Interactive process killer utilizing the Tk GUI toolkit.
# Uses the system's "ps" command to get a list of the currently-runnin
+g processes,
# and the system's "kill" command to send them signals.
# My machine's "ps", when run with "ps ux", gives output like the foll
# falkkin    531  0.0  1.4  2316 1380 tty1     S    08:53   0:00 -bash
# My machine's "kill" is of the form "kill -s $signal $pid".
# Supported signals include TERM, STOP, CONT, INT, HUP, and KILL.
# You'll need to modify this script if your "ps" command formats outpu
+t differently
# or your "kill" command has different syntax.
# Eventually, I hope to make this script more portable.
# Authored by Colin McMillen (e-mail: colin at and 
# into the public domain. You may use, copy, redistribute, and modify 
+this program
# without any restrictions.
use strict;
use Tk;  

my $VERSION = v0.1;

# Choose the options to send to "ps". Defaults to "ps ux".
my $PS_OPTIONS = $ARGV[0] || "ux";

# Index (starting from 0) of the fields for process ID and command nam
my $PID_FIELD = 1;

# Create the main window and add an informational label.
my $top = MainWindow->new(); 
$top->Label(text => "Double-click on the process you would like to kil

# Create a frame to hold the process list and its scrollbar.
my $frame1 = $top->Frame()->pack(fill => "both", expand => "y");

# Get the actual process list and discard the first line of output (wh
# contains informational headers that we want to ignore).
my @processes = `ps $PS_OPTIONS`;
shift @processes;

# Use the process list to create a listbox. Add the listbox to $frame1
my $process_list = $frame1->Listbox(width => 80,
                                    height => 15)->pack(side => "left"
                                                        fill => "both"
                                                        expand => "y")

# Split each line of output into fields, based on whitespace. Then, ge
+t the
# process ID and command name out of the fields, and add them to the l
foreach my $process (@processes) {
    my (@fields) = split(/\s+/, $process);
    my $pid = $fields[$PID_FIELD];
    my @command = @fields[ $COMMAND_FIELD .. @fields-1 ];
    my $command = join(" ", @command);
    $process_list->insert("end","$pid $command");

# Bind a double-click on the listbox to the kill() subroutine.
$process_list->bind("<Double-1>", \&kill);

# Create a scrollbar to scroll the listbox vertically and add it to $f
my $scrollbar = $frame1->Scrollbar(orient  => "vertical",
                                   width   => 10,
                                   command => ["yview", $process_list]
                                   )->pack(side => "left", fill => "y"
$process_list->configure(yscrollcommand => ["set", $scrollbar]);

# Create a frame to hold radiobuttons for choosing a signal.
my $frame2 = $top->Frame()->pack();

# Create the radiobuttons inside $frame2.
$frame2->Label(text => "Choose a signal:")->pack(side => "left");
my $signal = "TERM";
$frame2->Radiobutton(variable => \$signal, 
                     text     => "Terminate", 
                     value    => "TERM")->pack(side => "left");
$frame2->Radiobutton(variable => \$signal, 
                     text     => "Stop", 
                     value    => "STOP")->pack(side => "left");
$frame2->Radiobutton(variable => \$signal, 
                     text     => "Continue", 
                     value    => "CONT")->pack(side => "left");
$frame2->Radiobutton(variable => \$signal,
                     text     => "Interrupt", 
                     value    => "INT")->pack(side => "left");
$frame2->Radiobutton(variable => \$signal, 
                     text     => "Hangup", 
                     value    => "HUP")->pack(side => "left");
$frame2->Radiobutton(variable => \$signal, 
                     text     => "Kill", 
                     value    => "KILL")->pack(side => "left");

# Hand control of the program off to the GUI.

# Subroutine called when a field in the listbox is double-clicked.
# The process ID of the process is the first field in the listbox's ac
+tive item.
# The signal to send the process is set by the radiobuttons and stored
+ in
# the variable $signal.
sub kill {
    my $process = $process_list->get('active');
    my ($pid) = split(/ /, $process);
    return unless $pid;
    system("kill -s $signal $pid");
Replies are listed 'Best First'.
by turnstep (Parson) on Dec 26, 2000 at 08:15 UTC
    Some friendly notes:
    1. Go ahead and post the code here - I looked, and it is not that long. Actual code is always preferred to an offsite link, unless the code is very very long or is already on CPAN.
    2. Once it has been posted here and critiqued/admired by the illustrious monks, consider sending it to CPAN. Not everything on CPAN is a module, either, if you just want to keep it as a simple script.
      1. Thanks for pointing that out -- when I submitted the post yesterday, I did include the actual code. I think it somehow got lost when the post was officially moderated (or something). It should be fixed now.

      2. I've considered submitting it to CPAN, but am mildly intimidated by the whole process... this is my first piece of publically available code (in Perl or any language.) I guess if the monks critique it, and anyone out there thinks it's actually useful, I'd definitely want to submit it.

by xphase_work (Pilgrim) on May 07, 2001 at 19:06 UTC
    Nice script, I just finished making it run on solaris 2.7
    on sparc. I also changed the look slightly so that it
    displays the username, pid, and command. Also, the script
    now only displays processes the user running the script
    owns. Finally the script refreshes the process list once
    every 10 seconds. The only issue I have with the refresh
    is that the scrollbar keeps reseting to the top, but I
    haven't spent much time looking at it. Also, the
    continue signal doesn't work


    The code is posted below:

    NOTE:perl is located in a strange location on my machine
    please change to where ever it's located on your machine.

by JSchmitz (Canon) on May 04, 2001 at 20:18 UTC
    I like this - It runs no problem on Solaris although on Windoze the gui comes up but there are no processes shown where do I hack this sucker to show Windoze processes?
      Well, it currently will only work on UNIX machines, because it relies on the output of the "ps" command. I've not looked into adapting it for windows, but if you were interested, you could maybe take a look at the various Win32:: modules. (Perhaps Win32::Process would be of help.)