| #! /usr/bin/env python |
| |
| # Tkinter interface to SYSV `ps' and `kill' commands. |
| |
| from tkinter import * |
| |
| if TkVersion < 4.0: |
| raise ImportError("This version of svkill requires Tk 4.0 or later") |
| |
| import subprocess |
| import os |
| |
| user = os.environ['LOGNAME'] |
| |
| class BarButton(Menubutton): |
| def __init__(self, master=None, **cnf): |
| Menubutton.__init__(self, master, **cnf) |
| self.pack(side=LEFT) |
| self.menu = Menu(self, name='menu') |
| self['menu'] = self.menu |
| |
| class Kill(Frame): |
| # List of (name, option, pid_column) |
| view_list = [ |
| ('Default', ''), |
| ('Every (-e)', '-e'), |
| ('Non process group leaders (-d)', '-d'), |
| ('Non leaders with tty (-a)', '-a'), |
| ('For this user (-u %s)' % user, '-u %s' % user), |
| ] |
| format_list = [ |
| ('Default', '', 0), |
| ('Long (-l)', '-l', 3), |
| ('Full (-f)', '-f', 1), |
| ('Full Long (-f -l)', '-l -f', 3), |
| ('Session and group ID (-j)', '-j', 0), |
| ('Scheduler properties (-c)', '-c', 0), |
| ] |
| def kill(self, selected): |
| c = self.format_list[self.format.get()][2] |
| pid = selected.split()[c] |
| os.system('kill -9 ' + pid) |
| self.do_update() |
| def do_update(self): |
| format = self.format_list[self.format.get()][1] |
| view = self.view_list[self.view.get()][1] |
| s = subprocess.getoutput('ps %s %s' % (view, format)) |
| list = s.split('\n') |
| self.header.set(list[0] + ' ') |
| del list[0] |
| self.frame.list.delete(0, AtEnd()) |
| for line in list: |
| self.frame.list.insert(0, line) |
| def do_motion(self, e): |
| e.widget.select_clear('0', 'end') |
| e.widget.select_set(e.widget.nearest(e.y)) |
| def do_leave(self, e): |
| e.widget.select_clear('0', 'end') |
| def do_1(self, e): |
| self.kill(e.widget.get(e.widget.nearest(e.y))) |
| def __init__(self, master=None, **cnf): |
| Frame.__init__(self, master, **cnf) |
| self.pack(expand=1, fill=BOTH) |
| self.bar = Frame(self, name='bar', relief=RAISED, |
| borderwidth=2) |
| self.bar.pack(fill=X) |
| self.bar.file = BarButton(self.bar, text='File') |
| self.bar.file.menu.add_command( |
| label='Quit', command=self.quit) |
| self.bar.view = BarButton(self.bar, text='View') |
| self.bar.format = BarButton(self.bar, text='Format') |
| self.view = IntVar(self) |
| self.view.set(0) |
| self.format = IntVar(self) |
| self.format.set(0) |
| for num in range(len(self.view_list)): |
| label, option = self.view_list[num] |
| self.bar.view.menu.add_radiobutton( |
| label=label, |
| command=self.do_update, |
| variable=self.view, |
| value=num) |
| for num in range(len(self.format_list)): |
| label, option, col = self.format_list[num] |
| self.bar.format.menu.add_radiobutton( |
| label=label, |
| command=self.do_update, |
| variable=self.format, |
| value=num) |
| self.bar.tk_menuBar(self.bar.file, |
| self.bar.view, |
| self.bar.format) |
| self.frame = Frame(self, relief=RAISED, borderwidth=2) |
| self.frame.pack(expand=1, fill=BOTH) |
| self.header = StringVar(self) |
| self.frame.label = Label( |
| self.frame, relief=FLAT, anchor=NW, borderwidth=0, |
| textvariable=self.header) |
| self.frame.label.pack(fill=Y, anchor=W) |
| self.frame.vscroll = Scrollbar(self.frame, orient=VERTICAL) |
| self.frame.list = Listbox( |
| self.frame, |
| relief=SUNKEN, |
| width=40, height=10, |
| selectbackground='#eed5b7', |
| selectborderwidth=0, |
| selectmode=BROWSE, |
| yscroll=self.frame.vscroll.set) |
| self.frame.vscroll['command'] = self.frame.list.yview |
| self.frame.vscroll.pack(side=RIGHT, fill=Y) |
| self.frame.list.pack(expand=1, fill=BOTH) |
| self.update = Button(self, text='Update', |
| command=self.do_update) |
| self.update.pack(fill=X) |
| self.frame.list.bind('<Motion>', self.do_motion) |
| self.frame.list.bind('<Leave>', self.do_leave) |
| self.frame.list.bind('<1>', self.do_1) |
| self.do_update() |
| |
| if __name__ == '__main__': |
| kill = Kill(None, borderwidth=5) |
| kill.winfo_toplevel().title('Tkinter Process Killer (SYSV)') |
| kill.winfo_toplevel().minsize(1, 1) |
| kill.mainloop() |