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");