KP script

#!/usr/bin/wish -f
# 
# ----------------------------------------- 
# KillProc -- signal a hung/runaway process 
# ----------------------------------------- 
#
     
lappend auto_path "/usr/local/lib/tkextra"
     
# ------------------------------
# Application-specific globals
# ------------------------------
     
# arguments for the 'ps' command (change to suite your 'ps') 
# SysV:
set ps_user "-fu"
set ps_all "-ef"
     
# pre-SysV:
# set ps_user "-au | grep "
# set ps_all "-ax"
     
# initial values for menu options 
set user   $env(LOGNAME)
set signal -INT
     
# ------------------------------
# Application-specific routines
# ------------------------------
     
#
# Get the selected line(s) from the list-box, 
# extract the pid, signal the process
#
proc kill_proc {} {
 global user signal
     
 #
 # Get the list of selected line numbers
 # If the list is empty, nothing is selected, so return 
 #
 set sellist [.ps.list curselection]
 if {[llength $sellist] == 0} {
  return
 }
     
 #
 # For each entry in the selected-lines-list,
 # Get the line, extract the pid, append to a list of PID's 
 # (optional: filter out critical processes that shouldn't be touched) 
 #
 foreach index $sellist {
  set line [.ps.list get $index]
  scan $line "%s %d" uid pid
  if {$pid <= 0} {
   continue
  }
     
  # Use this to skip over "must-not-kill" processes: 
  # if {[string match "*xyz*" $line]} {
  # err "$line\n\nLooks like a 'xyz' process;\n Should not kill it!" 
  #  continue
  # }
     
  lappend pid_list $pid 
 }
     
 #
 # Construct a "kill" command line,
 # Execute it and get the error return 
 #
 set cmd [list exec kill $signal $pid_list] 
 set ret [catch $cmd err]
     
 #
 # If there was a problem signalling a process, 
 # Let the user know
 #
 if {$ret == 1} {
  msg "Could not kill a process;\nit's already gone?" 
  return
 }
     
 #
 # Refresh the process list
 #
 scan_proc
}
     
#
# Do a "ps", collect the output, put into a list-box 
#
proc scan_proc {} {
 global user ps_user ps_all
     
 #
 # Generate the "ps" command line
 #
 if {$user == "Any"} {
  set cmd "|ps $ps_all | sort"
 } {
  set cmd "|ps $ps_user $user | sort"
 }
     
 #
 # Evaluate the command line
 # Get the resulting list of lines
 # Fill the list-box with the lines
 #
 fill_list  .ps.list  [read_list $cmd]  0
}
     
     
# ------------------------------
# GUI Specific Routines
# ------------------------------
     
     
#
# Make the main control panel -- fill it with some controls 
#
proc make_control_panel { } {
 global user signal
     
 #
 # Setup some window-manager options
 #
 wm title    . "Process Killer"
 wm iconname . "KP"
 wm command  . "KillProc"
     
 #
 # Make the menu
 #
 menu_bar .mbar 0 \
  {menu File}    \
  {cmd  Quit exit}   \
  {end left}    \
  {menu Signals}    \
  {radio " 1 Hangup"     signal "-HUP"}  \ 
  {radio " 2 Interrupt"  signal "-INT"}  \ 
  {radio " 3 Quit"       signal "-QUIT"} \
  {radio " 9 Kill"       signal "-KILL"} \
  {radio "14 Alarm"      signal "-ALRM"} \
  {radio "15 Terminate"  signal "-TERM"} \ 
  {radio "23 Stop"       signal "-STOP"} \
  {radio "24 Term. Stop" signal "-TSTP"} \ 
  {radio "25 Continue"   signal "-CONT"} \ 
  {end left}   \
  {menu User}   \
  {radio Any  user Any}  \
  {radio Me  user $user}  \
  {sep}      \
  {radio moe  user moe}  \
  {radio curly  user curly}  \
  {radio larry  user larry}  \
  {end left}
     
 #
 # Make the scrolling list-box
 #
 mk_list .ps kill_proc
     
 #
 # Make the control buttons
 #
 buttons .cmd  ""  left  0 \
  {width 4}   \
  {cmd "Scan" scan_proc} \
  {cmd "Kill" kill_proc} \
  {cmd "Quit" exit }
     
 # pack menu   -> top
 # pack btns   -> on the bottom
 # pack scroll-box -> in the middle
     
 pack .mbar  -side top    -fill x 
 pack .ps    -side top    -fill both -expand yes 
 pack .cmd   -side bottom -fill x 
}
     
     
# ------------------------------
# M A I N L I N E
# ------------------------------
     
make_control_panel
scan_proc
     
# wait for the User menu item to change, then refresh the list-box 
while {1} {
 tkwait variable user
 scan_proc
}
     
# ------------------------------
# The End.
# ------------------------------
     

