|
1 #! /usr/bin/env python |
|
2 |
|
3 # Tkinter interface to SYSV `ps' and `kill' commands. |
|
4 |
|
5 from Tkinter import * |
|
6 |
|
7 if TkVersion < 4.0: |
|
8 raise ImportError, "This version of svkill requires Tk 4.0 or later" |
|
9 |
|
10 from string import splitfields |
|
11 from string import split |
|
12 import commands |
|
13 import os |
|
14 |
|
15 user = os.environ['LOGNAME'] |
|
16 |
|
17 class BarButton(Menubutton): |
|
18 def __init__(self, master=None, **cnf): |
|
19 apply(Menubutton.__init__, (self, master), cnf) |
|
20 self.pack(side=LEFT) |
|
21 self.menu = Menu(self, name='menu') |
|
22 self['menu'] = self.menu |
|
23 |
|
24 class Kill(Frame): |
|
25 # List of (name, option, pid_column) |
|
26 view_list = [ |
|
27 ('Default', ''), |
|
28 ('Every (-e)', '-e'), |
|
29 ('Non process group leaders (-d)', '-d'), |
|
30 ('Non leaders with tty (-a)', '-a'), |
|
31 ('For this user (-u %s)' % user, '-u %s' % user), |
|
32 ] |
|
33 format_list = [ |
|
34 ('Default', '', 0), |
|
35 ('Long (-l)', '-l', 3), |
|
36 ('Full (-f)', '-f', 1), |
|
37 ('Full Long (-f -l)', '-l -f', 3), |
|
38 ('Session and group ID (-j)', '-j', 0), |
|
39 ('Scheduler properties (-c)', '-c', 0), |
|
40 ] |
|
41 def kill(self, selected): |
|
42 c = self.format_list[self.format.get()][2] |
|
43 pid = split(selected)[c] |
|
44 os.system('kill -9 ' + pid) |
|
45 self.do_update() |
|
46 def do_update(self): |
|
47 format = self.format_list[self.format.get()][1] |
|
48 view = self.view_list[self.view.get()][1] |
|
49 s = commands.getoutput('ps %s %s' % (view, format)) |
|
50 list = splitfields(s, '\n') |
|
51 self.header.set(list[0] + ' ') |
|
52 del list[0] |
|
53 self.frame.list.delete(0, AtEnd()) |
|
54 for line in list: |
|
55 self.frame.list.insert(0, line) |
|
56 def do_motion(self, e): |
|
57 e.widget.select_clear('0', 'end') |
|
58 e.widget.select_set(e.widget.nearest(e.y)) |
|
59 def do_leave(self, e): |
|
60 e.widget.select_clear('0', 'end') |
|
61 def do_1(self, e): |
|
62 self.kill(e.widget.get(e.widget.nearest(e.y))) |
|
63 def __init__(self, master=None, **cnf): |
|
64 apply(Frame.__init__, (self, master), cnf) |
|
65 self.pack(expand=1, fill=BOTH) |
|
66 self.bar = Frame(self, name='bar', relief=RAISED, |
|
67 borderwidth=2) |
|
68 self.bar.pack(fill=X) |
|
69 self.bar.file = BarButton(self.bar, text='File') |
|
70 self.bar.file.menu.add_command( |
|
71 label='Quit', command=self.quit) |
|
72 self.bar.view = BarButton(self.bar, text='View') |
|
73 self.bar.format = BarButton(self.bar, text='Format') |
|
74 self.view = IntVar(self) |
|
75 self.view.set(0) |
|
76 self.format = IntVar(self) |
|
77 self.format.set(0) |
|
78 for num in range(len(self.view_list)): |
|
79 label, option = self.view_list[num] |
|
80 self.bar.view.menu.add_radiobutton( |
|
81 label=label, |
|
82 command=self.do_update, |
|
83 variable=self.view, |
|
84 value=num) |
|
85 for num in range(len(self.format_list)): |
|
86 label, option, col = self.format_list[num] |
|
87 self.bar.format.menu.add_radiobutton( |
|
88 label=label, |
|
89 command=self.do_update, |
|
90 variable=self.format, |
|
91 value=num) |
|
92 self.bar.tk_menuBar(self.bar.file, |
|
93 self.bar.view, |
|
94 self.bar.format) |
|
95 self.frame = Frame(self, relief=RAISED, borderwidth=2) |
|
96 self.frame.pack(expand=1, fill=BOTH) |
|
97 self.header = StringVar(self) |
|
98 self.frame.label = Label( |
|
99 self.frame, relief=FLAT, anchor=NW, borderwidth=0, |
|
100 font='*-Courier-Bold-R-Normal-*-120-*', |
|
101 textvariable=self.header) |
|
102 self.frame.label.pack(fill=Y, anchor=W) |
|
103 self.frame.vscroll = Scrollbar(self.frame, orient=VERTICAL) |
|
104 self.frame.list = Listbox( |
|
105 self.frame, |
|
106 relief=SUNKEN, |
|
107 font='*-Courier-Medium-R-Normal-*-120-*', |
|
108 width=40, height=10, |
|
109 selectbackground='#eed5b7', |
|
110 selectborderwidth=0, |
|
111 selectmode=BROWSE, |
|
112 yscroll=self.frame.vscroll.set) |
|
113 self.frame.vscroll['command'] = self.frame.list.yview |
|
114 self.frame.vscroll.pack(side=RIGHT, fill=Y) |
|
115 self.frame.list.pack(expand=1, fill=BOTH) |
|
116 self.update = Button(self, text='Update', |
|
117 command=self.do_update) |
|
118 self.update.pack(fill=X) |
|
119 self.frame.list.bind('<Motion>', self.do_motion) |
|
120 self.frame.list.bind('<Leave>', self.do_leave) |
|
121 self.frame.list.bind('<1>', self.do_1) |
|
122 self.do_update() |
|
123 |
|
124 if __name__ == '__main__': |
|
125 kill = Kill(None, borderwidth=5) |
|
126 kill.winfo_toplevel().title('Tkinter Process Killer (SYSV)') |
|
127 kill.winfo_toplevel().minsize(1, 1) |
|
128 kill.mainloop() |