diff --git a/smem b/smem index 0412d9d..c3dfe68 100755 --- a/smem +++ b/smem @@ -1,5 +1,5 @@ #!/usr/bin/python -import re, os, sys, pwd, grp, optparse +import re, os, sys, pwd, grp, optparse, errno def pids(): '''get a list of processes''' @@ -113,10 +113,9 @@ def showpids(): fields = dict( pid=('PID', lambda n: n, '% 5s', lambda x: len(p)), - uid=('UID', username, '%-5s', None), - user=('User', showuser, '%-8s', None), + user=('User', showuser, '%-8s', lambda x: len(dict.fromkeys(x))), name=('Name', pidname, '%-24.24s', None), - command=('Command', pidcmd, '%-24.24s', None), + command=('Command', pidcmd, '%-27.27s', None), swap=('Swap',lambda n: pt[n]['swap'], '% 8s', sum), uss=('USS', lambda n: pt[n]['private_clean'] + pt[n]['private_dirty'], '% 8s', sum), @@ -147,7 +146,6 @@ def maptotals(pids): totals[name] = t except: raise - print len(totals), totals.keys()[0] return totals def showmaps(): @@ -156,7 +154,7 @@ def showmaps(): fields = dict( map=('Map', lambda n: n, '%-24.24s', len), - count=('Count', lambda n: pt[n]['count'], '% 8s', sum), + count=('Count', lambda n: pt[n]['count'], '% 5s', sum), swap=('Swap',lambda n: pt[n]['swap'], '% 8s', sum), uss=('USS', lambda n: pt[n]['private_clean'] + pt[n]['private_dirty'], '% 8s', sum), @@ -167,6 +165,51 @@ def showmaps(): showtable(pt.keys(), fields, columns.split(), options.sort or 'pss') +def usertotals(pids): + totals = {} + for pid in pids: + try: + maps = pidmaps(pid) + except: + raise + user = piduser(pid) + if user not in totals: + t = dict(size=0, rss=0, pss=0, shared_clean=0, + shared_dirty=0, private_clean=0, count=0, + private_dirty=0, referenced=0, swap=0) + else: + t = totals[user] + + for m in maps.iterkeys(): + for k in t: + t[k] += maps[m].get(k, 0) + + t['count'] += 1 + totals[user] = t + return totals + +def showusers(): + p = pids() + pt = usertotals(p) + + def showuser(p): + if options.numeric: + return p + return username(p) + + fields = dict( + user=('User', showuser, '%-8s', None), + count=('Count', lambda n: pt[n]['count'], '% 5s', sum), + swap=('Swap',lambda n: pt[n]['swap'], '% 8s', sum), + uss=('USS', lambda n: pt[n]['private_clean'] + + pt[n]['private_dirty'], '% 8s', sum), + rss=('RSS', lambda n: pt[n]['rss'], '% 8s', sum), + pss=('PSS', lambda n: pt[n]['pss'], '% 8s', sum), + ) + columns = options.columns or 'user count swap uss pss rss' + + showtable(pt.keys(), fields, columns.split(), options.sort or 'pss') + def showtable(rows, fields, columns, sort): header = "" format = "" @@ -180,7 +223,7 @@ def showtable(rows, fields, columns, sort): r = [fields[c][1](n) for c in columns] l.append((fields[sort][1](n), r)) - l.sort() + l.sort(reverse=bool(options.reverse)) if not options.no_header: print header @@ -214,12 +257,22 @@ parser.add_option("-c", "--columns", type="str", help="columns to show") parser.add_option("-m", "--mappings", action="store_true", help="show mappings") +parser.add_option("-u", "--users", action="store_true", + help="show users") +parser.add_option("-r", "--reverse", action="store_true", + help="reverse sort") defaults = {} parser.set_defaults(**defaults) (options, args) = parser.parse_args() -if options.mappings: - showmaps() -else: - showpids() +try: + if options.mappings: + showmaps() + elif options.users: + showusers() + else: + showpids() +except IOError, e: + if e.errno == errno.EPIPE: + pass