2
# psax.py; illustration of curses library
3
# runs the shell command ps ax and saves the last lines of its output,
4
# as many as the window will fit; allows the user to move up and down
5
# within the window, killing those processes
10
move highlight up a line
12
move highlight down a line
14
kill process in currently highlighted line
16
re-run 'ps ax' for update
19
# possible extensions: allowing scrolling, so that the user could go
20
# through all the ps ax output; allow wraparound for long lines; ask
21
# user to confirm before killing a process
23
import curses, os, sys, traceback
27
scrn = None # will point to Curses window object
28
cmdoutlines = [] # output of 'ps ax' (including the lines we don't
30
# use, for possible future extension)
32
winrow = None # current row position in screen
33
startrow = None # index of first row in cmdoutlines to be displayed
35
p = os.popen('ps ax','r')
40
# don't allow line wraparound, so truncate long lines
43
# remove EOLN if it is still there
44
if ln[-1] == '\n': ln = ln[:-1]
46
gb.cmdoutlines.append(ln)
49
# display last part of command output (as much as fits in screen)
53
# prepare to paint the (last part of the) 'ps ax' output on the screen
55
ncmdlines = len(gb.cmdoutlines)
56
# two cases, depending on whether there is more output than screen rows
57
if ncmdlines <= curses.LINES:
60
gb.startrow = ncmdlines - curses.LINES - 1
61
nwinlines = curses.LINES
62
lastrow = gb.startrow + nwinlines - 1
65
for ln in gb.cmdoutlines[gb.startrow:lastrow]:
66
gb.scrn.addstr(gb.winrow,0,ln)
71
# last line highlighted
72
gb.scrn.addstr(gb.winrow,0,gb.cmdoutlines[lastrow],curses.A_BOLD)
75
# move highlight up/down one line
78
# ignore attempts to go off the edge of the screen
79
if tmp >= 0 and tmp < curses.LINES:
80
# unhighlight the current line by rewriting it in default attributes
81
gb.scrn.addstr(gb.winrow,0,gb.cmdoutlines[gb.startrow+gb.winrow])
82
# highlight the previous/next line
84
ln = gb.cmdoutlines[gb.startrow+gb.winrow]
85
gb.scrn.addstr(gb.winrow,0,ln,curses.A_BOLD)
88
# kill the highlighted process
90
ln = gb.cmdoutlines[gb.startrow+gb.winrow]
91
pid = int(ln.split()[0])
101
gb.scrn = curses.initscr()
104
# rpdb.set_trace() (I used RPDB for debugging)
105
# run 'ps ax' and process the output
107
# display in the window
114
if c == 'u': updown(-1)
115
elif c == 'd': updown(1)
116
elif c == 'r': rerun()
117
elif c == 'k': kill()
127
if __name__ =='__main__':
131
# print error message re exception
132
traceback.print_exc()