#!/usr/bin/python # -*- coding: utf-8 -*- """ #------------------------------------------------------------------------------- processes.py - version 7 by Vlad George #------------------------------------------------------------------------------- Description: This script pipes a process manipulation menu into the openbox menu. Usage: Just place this script in ~/.config/openbox/scripts, make it executable; if you want you can enlist the processes which should not be shown in the unwanted_procs list below, then add following to your ~/.config/openbox/menu.xml: "... ......" and reconfigure openbox. To enable cpu usage display uncomment the lines marked with (***) (lines 106-108 and 146). Note: You need 'ps'. To enable cpulimit just uncomment the lines marked with (#*#) (lines 158-169). Note: You need 'cpulimit'. Get it from here: "http://cpulimit.sourceforge.net" Changelog: 20.02.07: 7th version - added "-z" flag to cpulimit; added ValueError handling for printXml; added --title flag 04.12.07: 6th version - added cpulimit; to enable it just uncomment the lines marked with (#*#) 18.11.07: 5th version - processes alphabetically sorted 22.10.07: 4th version - totally removed SleepAVG from script. for kernels < 2.6.20 please use earlier versions. simplified cpu usage command. 07.07.07: 3rd version - added cpu usage; since SleepAVG was removed from /proc (2.6.20), it will be only displayed depending on running kernel version 17.02.07: 2nd version - shortened procData #------------------------------------------------------------------------------- This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. http://www.fsf.org/ """ #------------------------------------------------------------------------------- # User set variables #------------------------------------------------------------------------------- ## processes (e.g. daemons, bash, this script, etc) you do not want to be shown in the process manipulation menu: ## !!! don´t forget quotes !!! ## unwanted_procs = ["processes.py","ssh-agent","gconfd-2","dbus-daemon","dbus-launch","kded","dcopserver","..."] unwanted_procs = ["processes.py","sh","bash","netstat","ssh-agent","gconfd-2","gnome-pty-helpe","dbus-daemon","dbus-launch",\ "visibility","pypanel","knotify","kdeinit","klauncher","kded","dcopserver","kio_file"] ## if you want a title (separator) for the processes menu you can set it here; to show the title use the "--title" flag (/path/to/processes.py --title) processes_menu_title = "processes" #------------------------------------------------------------------------------- # Script #------------------------------------------------------------------------------- def _procName(pid): """ pid -> processname """ try: return file(os.path.join('/proc', str(pid), 'status'), 'r').readline().split()[1] except IOError: return None def _procData(pid): """ pid -> info_list = [State, VmSize, VmLck, VmRSS, VmLib, priority(nice), command, cpu usage] """ info_list = list() ## from /proc//status get State, VmSize, VmLck, VmRSS, VmLib status_file = file(os.path.join("/proc", str(pid), "status"), 'r') status = status_file.readlines() status_file.close() [info_list.append(status[i].split(":")[1].lstrip().rstrip("\n")) for i in (1,11,12,14,18)] ## from /proc//stat get priority(nicelevel) priority_file = file(os.path.join('/proc', str(pid), 'stat'), 'r') priority = priority_file.read() priority_file.close() info_list.append(priority.split()[18]) ## from /proc//cmdline get command cmdline_file = file(os.path.join("/proc", str(pid),"cmdline"),'r') cmdline = cmdline_file.read() cmdline_file.close() info_list.append(" ".join(cmdline.split("\x00")[:-1])) ## from "ps --pid %s -o pcpu=" get cpu usage for pid ## (***) comment out following three lines to disable cpu usage display #ps_cpu_for_pid = 'ps --pid %s -o pcpu=' % (pid) #ps_cmd = os.popen(ps_cpu_for_pid).readline() #info_list.append(ps_cmd) ## (***) return info_list def userPidFilter(): """ fiters pids from /proc// for user who owns script excluding the unwanted_procs ids """ uid = os.stat(sys.argv[0])[4] uid_pids = list() for pid in os.listdir("/proc"): if os.path.isdir(os.path.join("/proc", pid)): try: if os.stat(os.path.join("/proc", pid))[4] == uid : uid_pids.append(int(pid)) except ValueError: pass ## sort pids according to process names pid_proc_list = list() [pid_proc_list.append((i, _procName(i))) for i in uid_pids] def removeProcsFromList(pid): process = _procName(pid) if process in unwanted_procs: pid_proc_list.remove((pid, process)) map(removeProcsFromList, uid_pids) pid_proc_list.sort(key = lambda t:t[1].lower()) return [pid_proc_list[i][0] for i in xrange(len(pid_proc_list))] def printXml(pid): """ xml output for each pid _procData(pid)=[[0]-State, [1]-VmSize, [2]-VmLck, [3]-VmRSS, [4]-VmLib, [5]-priority(nice), [6]-command, [(***)optional: [7]-cpu usage]] """ proc_info = _procData(pid) ## (***) uncomment following line to enable cpu usage display: #print 'true' ## (***) print '' % (pid, int(proc_info[1].split()[0])/1024) print 'true' % (proc_info[3]) print 'true' % (proc_info[4]) print 'true' % (proc_info[2]) print 'true' % (proc_info[1]) print '' print '' ## (#*#) uncomment following lines to enable cpulimit: #print '' % (pid) #print 'cpulimit -p %s -z -l 10' % (pid) #print 'cpulimit -p %s -z -l 20' % (pid) #print 'cpulimit -p %s -z -l 30' % (pid) #print 'cpulimit -p %s -z -l 40' % (pid) #print 'cpulimit -p %s -z -l 50' % (pid) #print 'cpulimit -p %s -z -l 60' % (pid) #print 'cpulimit -p %s -z -l 70' % (pid) #print 'cpulimit -p %s -z -l 80' % (pid) #print 'cpulimit -p %s -z -l 90' % (pid) #print 'cpulimit -p %s -z -l 100' % (pid) #print '' ## (#*#) print '' % (pid, proc_info[5]) print 'renice -10 %s' % (pid) print 'renice -5 %s' % (pid) print 'renice 0 %s' % (pid) print 'renice 5 %s' % (pid) print 'renice 10 %s' % (pid) print 'renice 15 %s' % (pid) print 'renice 19 %s' % (pid) print '' print '' % (pid, proc_info[0]) print 'kill -SIGSTOP %s' % (pid) print 'kill -SIGCONT %s' % (pid) print '' print '' % (pid) print 'kill -TERM %s' % (pid) print 'kill -HUP %s' % (pid) print 'kill -INT %s' % (pid) print 'kill -KILL %s' % (pid) print '' print '' print '' % (pid) print 'true' % (proc_info[6]) print '' print '%s' % (proc_info[6]) print '' def generateMenu(pid): """ generate main menu """ print '' % (pid, _procName(pid), sys.argv[0], pid) #------------------------------------------------------------------------------- # Main #------------------------------------------------------------------------------- import os, sys #-------------------------# if __name__ == "__main__" : #-------------------------# print '' print '' args = sys.argv[1:] if ('--pid' in args): try: printXml(int(sys.argv[2])) except ValueError and IOError: pass else: if ('--title' in args): print '' % (processes_menu_title) else: pass map(generateMenu, userPidFilter()) print '' # vim: set ft=python nu ts=4 sw=4 :