[Zope-Checkins] CVS: Zope/lib/python/Products/ForensicLogger/procps/linuxproc-1.0 - README.txt:1.1.2.1 linuxproc.py:1.1.2.1 pystat.py:1.1.2.1
Andreas Jung
andreas@zope.com
Mon, 22 Oct 2001 15:01:07 -0400
Update of /cvs-repository/Zope/lib/python/Products/ForensicLogger/procps/linuxproc-1.0
In directory cvs.zope.org:/tmp/cvs-serv32212/ForensicLogger/procps/linuxproc-1.0
Added Files:
Tag: ajung-forensiclogging
README.txt linuxproc.py pystat.py
Log Message:
added
=== Added File Zope/lib/python/Products/ForensicLogger/procps/linuxproc-1.0/README.txt ===
linuxproc -- A Python module for investigating data stored in Linux' /proc fs.
This module has been tested under Linux kernel versions 2.2.18 and 2.4.2.
For general Linux /proc filesystem info, see your Linux source tree's proc
documentation file (on my system it's /usr/src/linux/Documentation/proc.txt).
Most of the data exposed to Python is performance-related so far.
An associated module is likely available if you're reading this file named
pystat.py, which is a python vmstat clone which uses the linuxproc module.
linuxproc API:
get_kernel_version() -- returns a tuple representing the kernel version,
e.g. ('2', '2', '18').
proc_statm(pid) -- returns a dictionary of items kept in a process'
/proc/%(pid)/statm file. The dict members are:
size total program size
resident size of in memory portions
shared number of the pages that are shared
trs number of pages that are 'code'
drs number of pages of data/stack
lrs number of pages of library
dt number of dirty pages
self_statm() -- returns proc_statm info for the running process
proc_stat() -- returns a dictionary of items kept in a process'
/proc/%pid/stat file. The members of the dict are below:
'pid', 'comm', 'state', 'ppid', 'pgrp', 'session', 'tty', 'tty_pgrp',
'flags', 'min_flt', 'cmin_flt', 'maj_flt', 'cmaj_flt', 'utime',
'stime', 'cutime', 'cstime', 'priority', 'nice', 'NULL',
'it_real_value', 'start_time', 'vsize', 'rss', 'rlim', 'start_code',
'end_code', 'start_stack', 'esp', 'eip', 'signal',
'blocked', 'sigign', 'sigcatch', 'wchan', 'nswap', 'cnswap',
'exit_signal', 'processor'
See the proc(5) manpage for info on these items.
self_stat() -- returns proc_stat info for the running process
loadavg() -- returns a dict representing /proc/loadavg info. Dict members:
'1min', '5min', '15min', 'running', 'cumulative'
See the proc(5) manpage for info on these items.
uptime() -- returns a dict representing /proc/uptime info. Dict members:
'uptime' -- number of seconds that the system has been up
'idle' -- number of seconds that the system has been idle
stat() -- returns a dict of dicts representing /proc/stat info.
Some of these items will not be available on your kernel version.
'cpu' : 'user', 'nice', 'system', 'idle'
'cpu0' : 'user', 'nice', 'system', 'idle'
'cpu1' : 'user', 'nice', 'system', 'idle'
'cpu2' : 'user', 'nice', 'system', 'idle'
'cpu3' : 'user', 'nice', 'system', 'idle'
'cpu4' : 'user', 'nice', 'system', 'idle'
'cpu5' : 'user', 'nice', 'system', 'idle'
'cpu6' : 'user', 'nice', 'system', 'idle'
'cpu7' : 'user', 'nice', 'system', 'idle'
'cpu8' : 'user', 'nice', 'system', 'idle'
'cpu9' : 'user', 'nice', 'system', 'idle'
'cpu10' : 'user', 'nice', 'system', 'idle'
'cpu11' : 'user', 'nice', 'system', 'idle'
'page' : 'in', 'out'
'swap' : 'in', 'out'
'intr' : 'interrupts'
'disk' : 'unknown1', 'unknown2', 'unknown3'
'disk_io' : 'unknown1', 'unknown2', 'unknown3'
'disk_rio' : 'unknown1', 'unknown2', 'unknown3'
'disk_wio' : 'unknown1', 'unknown2', 'unknown3'
'disk_rblk' : 'unknown1', 'unknown2', 'unknown3'
'disk_wblk' : 'unknown1', 'unknown2', 'unknown3'
'ctxt' : 'context_switches'
'btime' : 'boot_time'
'processes' : 'processes'
See the proc(5) manpage for more info on these items.
meminfo() -- return dict representing memory information related to
/proc/meminfo. Dict members:
'buffers' : buffer mem in K
'swapfree' : free swap space in K
'memshared': shared memory in K
'swaptotal': total swap space in K
'memtotal' : total memory in K
'memfree' : free memory in K
'cached' : cached memory in K
There may be other or different dict members depending on your
kernel version.
See the proc(5) manpage for more info on these items.
getrunners(getsleepers=0) -- return tuple in the form (running, swapped,
blocked), where each of running, swapped, or blocked is a list containing
the pids of processes which are running, swapped, or blocked.
If getsleepers is true, tuple returned is (running, swapped,
blocked, sleeping).
Chris McDonough
(chrism@zope.com)
=== Added File Zope/lib/python/Products/ForensicLogger/procps/linuxproc-1.0/linuxproc.py ===
##############################################################################
#
# Zope Public License (ZPL) Version 1.0
# -------------------------------------
#
# Copyright (c) Digital Creations. All rights reserved.
#
# This license has been certified as Open Source(tm).
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
#
# 1. Redistributions in source code must retain the above copyright
# notice, this list of conditions, and the following disclaimer.
#
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions, and the following disclaimer in
# the documentation and/or other materials provided with the
# distribution.
#
# 3. Digital Creations requests that attribution be given to Zope
# in any manner possible. Zope includes a "Powered by Zope"
# button that is installed by default. While it is not a license
# violation to remove this button, it is requested that the
# attribution remain. A significant investment has been put
# into Zope, and this effort will continue if the Zope community
# continues to grow. This is one way to assure that growth.
#
# 4. All advertising materials and documentation mentioning
# features derived from or use of this software must display
# the following acknowledgement:
#
# "This product includes software developed by Digital Creations
# for use in the Z Object Publishing Environment
# (http://www.zope.org/)."
#
# In the event that the product being advertised includes an
# intact Zope distribution (with copyright and license included)
# then this clause is waived.
#
# 5. Names associated with Zope or Digital Creations must not be used to
# endorse or promote products derived from this software without
# prior written permission from Digital Creations.
#
# 6. Modified redistributions of any form whatsoever must retain
# the following acknowledgment:
#
# "This product includes software developed by Digital Creations
# for use in the Z Object Publishing Environment
# (http://www.zope.org/)."
#
# Intact (re-)distributions of any official Zope release do not
# require an external acknowledgement.
#
# 7. Modifications are encouraged but must be packaged separately as
# patches to official Zope releases. Distributions that do not
# clearly separate the patches from the original work must be clearly
# labeled as unofficial distributions. Modifications which do not
# carry the name Zope may be packaged in any form, as long as they
# conform to all of the clauses above.
#
#
# Disclaimer
#
# THIS SOFTWARE IS PROVIDED BY DIGITAL CREATIONS ``AS IS'' AND ANY
# EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL DIGITAL CREATIONS OR ITS
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
# USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
# OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
# SUCH DAMAGE.
#
#
# This software consists of contributions made by Digital Creations and
# many individuals on behalf of Digital Creations. Specific
# attributions are listed in the accompanying credits file.
#
##############################################################################
""" module for investigating the Linux /proc filesystem
"""
import os, re, string
__version__ = '1.0'
DIGITS = {}
for d in "1234567890":
DIGITS[d] = 1
# linux 2_2_18 /proc/self/stat format
l2_2_18_procstat = [
'pid', 'comm', 'state', 'ppid', 'pgrp', 'session', 'tty', 'tty_pgrp',
'flags', 'min_flt', 'cmin_flt', 'maj_flt', 'cmaj_flt', 'utime',
'stime', 'cutime', 'cstime', 'priority', 'nice', 'NULL',
'it_real_value', 'start_time', 'vsize', 'rss', 'rlim', 'start_code',
'end_code', 'start_stack', 'esp', 'eip', 'signal',
'blocked', 'sigign', 'sigcatch', 'wchan', 'nswap', 'cnswap',
'exit_signal', 'processor'
]
# linux 2_2_18 /proc/loadavg format
l2_2_18_loadavg = ['1min', '5min', '15min', 'running', 'cumulative']
# linux 2_2_18 /proc/uptime format
l2_2_18_uptime = ['uptime', 'idle']
# linux 2_2_18 /proc/self/statm format
l2_2_18_procstatm = ['size', 'resident', 'shared', 'trs', 'drs', 'lrs', 'dt']
# linix 2_2_18 /proc/stat format
l2_2_18_stat = {
'cpu' : ['user', 'nice', 'system', 'idle'],
'disk' : ['unknown1', 'unknown2', 'unknown3'],
'disk_rio' : ['unknown1', 'unknown2', 'unknown3'],
'disk_wio' : ['unknown1', 'unknown2', 'unknown3'],
'disk_rblk' : ['unknown1', 'unknown2', 'unknown3'],
'disk_wblk' : ['unknown1', 'unknown2', 'unknown3'],
'page' : ['in', 'out'],
'swap' : ['in', 'out'],
'intr' : ['interrupts'],
'ctxt' : ['context_switches'],
'btime' : ['boot_time'],
'processes' : ['processes'],
}
# Linux 2_4_2 /proc/stat info
l2_4_2_stat = {
'cpu' : ['user', 'nice', 'system', 'idle'],
'cpu0' : ['user', 'nice', 'system', 'idle'],
'cpu1' : ['user', 'nice', 'system', 'idle'],
'cpu2' : ['user', 'nice', 'system', 'idle'],
'cpu3' : ['user', 'nice', 'system', 'idle'],
'cpu4' : ['user', 'nice', 'system', 'idle'],
'cpu5' : ['user', 'nice', 'system', 'idle'],
'cpu6' : ['user', 'nice', 'system', 'idle'],
'cpu7' : ['user', 'nice', 'system', 'idle'],
'cpu8' : ['user', 'nice', 'system', 'idle'],
'cpu9' : ['user', 'nice', 'system', 'idle'],
'cpu10' : ['user', 'nice', 'system', 'idle'],
'cpu11' : ['user', 'nice', 'system', 'idle'],
'page' : ['in', 'out'],
'swap' : ['in', 'out'],
'intr' : ['interrupts'],
'disk_io' : ['unknown1', 'unknown2', 'unknown3'],
'ctxt' : ['context_switches'],
'btime' : ['boot_time'],
'processes' : ['processes'],
}
version_map = {
('2','2','18'): { 'procstat' : l2_2_18_procstat,
'loadavg' : l2_2_18_loadavg,
'uptime' : l2_2_18_uptime,
'stat': l2_2_18_stat,
'procstatm' : l2_2_18_procstatm,
},
('2','4','2') : { 'procstat' : l2_2_18_procstat,
'loadavg' : l2_2_18_loadavg,
'uptime' : l2_2_18_uptime,
'stat': l2_4_2_stat,
'procstatm' : l2_2_18_procstatm,
},
}
version_guess_map = {
('2', '2') : ('2', '2', '18'),
('2', '4') : ('2', '4', '2'),
}
def get_struct(v, vmap=version_map.get, guess=version_guess_map.get):
return vmap(v) or vmap(guess(tuple(v[:2])))
def get_kernel_version():
version_match = re.compile(r'(\d+)\.(\d+)\.(\d+)').search
s = open('/proc/version').readline()
match = version_match(s)
return (match.group(1), match.group(2), match.group(3))
VERSION = get_kernel_version()
def proc_statm(pid):
return get_dict('procstatm', '/proc/%s/statm' % pid)
def self_statm():
return get_dict('procstatm', '/proc/self/statm')
def proc_stat(pid):
return get_dict('procstat', '/proc/%s/stat' % pid)
def self_stat():
return get_dict('procstat', '/proc/self/stat')
def loadavg():
return get_dict('loadavg', '/proc/loadavg')
def uptime():
return get_dict('uptime', '/proc/uptime')
def stat():
return get_multidict('stat', '/proc/stat')
def meminfo():
""" very expensive on 2.2 kernels, not so on 2.4 kernels """
lines = []; dict = {}
for line in open('/proc/meminfo').readlines():
if line:
l = string.split(line)
name, value = l[0], l[1:]
if name in('total:', 'Mem:', 'Swap:'):
continue
key = string.lower(name)[:-1]
value = value[0]
if value and DIGITS.has_key(value[0]):
value = maybe_number(value)
dict[key] = value
return dict
def getrunners(getsleepers=0, isdigit=DIGITS.has_key):
running = []; swapped = []; blocked = []; sleeping = []
addtorun = running.append
addtoswap = swapped.append
addtoblock = blocked.append
addtosleep = sleeping.append
names = os.listdir('/proc')
for name in names:
excp_happened = 0
if isdigit(name[0]):
try: stat = proc_stat(name)
except: excp_happened = 1
if excp_happened: continue
state = stat['state']
rss = stat['rss']
if getsleepers and state == "S":
addtosleep(name)
elif state == "R":
if rss > 0: addtorun(name)
else: addtoswap(name)
elif state == "D":
if rss > 0: addtoblock(name)
else: addtoswap(name)
if getsleepers:
return running, blocked, swapped, sleeping
else:
return running, blocked, swapped
def get_dict(structname, filename, isdigit=DIGITS.has_key,
find=string.find):
lookup = get_struct(VERSION)[structname]
d = {}; i = 0
raw = string.split(open(filename).readline())
for value in raw:
if value and isdigit(value[0]):
value = maybe_number(value)
name = lookup[i]
d[name] = value
i = i + 1
return d
def get_multidict(structname, filename, isdigit=DIGITS.has_key,
find=string.find):
dict = {}
lookup = get_struct(VERSION)[structname]
for line in open(filename, 'r').readlines():
l = string.split(line)
category = l[0]
if not lookup.has_key(category):
continue
items = l[1:]
d = {}; i = 0
for name in lookup[category]:
value = items[i]
if value and isdigit(value[0]):
value = maybe_number(value)
d[name] = value
i = i + 1
dict[category] = d
return dict
def maybe_number(value, find=string.find, float=float, int=int):
try:
if find(value, '.') != -1:
return float(value)
else:
return int(value)
except ValueError:
return value
if __name__ == '__main__':
import time
start = time.time()
for x in xrange(100):
getrunners()
uptime()
loadavg()
self_statm()
self_stat()
stat()
meminfo()
end = time.time()
print end-start
#import sys
#sys.exit(0)
for key, value in self_stat().items():
print key, value
for key, value in loadavg().items():
print key, value
for key, value in uptime().items():
print key, value
for key, value in stat().items():
print key, value
for key, value in meminfo().items():
print key, value
for key, value in self_statm().items():
print key, value
=== Added File Zope/lib/python/Products/ForensicLogger/procps/linuxproc-1.0/pystat.py ===
#!/bin/python
##############################################################################
#
# Zope Public License (ZPL) Version 1.0
# -------------------------------------
#
# Copyright (c) Digital Creations. All rights reserved.
#
# This license has been certified as Open Source(tm).
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
#
# 1. Redistributions in source code must retain the above copyright
# notice, this list of conditions, and the following disclaimer.
#
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions, and the following disclaimer in
# the documentation and/or other materials provided with the
# distribution.
#
# 3. Digital Creations requests that attribution be given to Zope
# in any manner possible. Zope includes a "Powered by Zope"
# button that is installed by default. While it is not a license
# violation to remove this button, it is requested that the
# attribution remain. A significant investment has been put
# into Zope, and this effort will continue if the Zope community
# continues to grow. This is one way to assure that growth.
#
# 4. All advertising materials and documentation mentioning
# features derived from or use of this software must display
# the following acknowledgement:
#
# "This product includes software developed by Digital Creations
# for use in the Z Object Publishing Environment
# (http://www.zope.org/)."
#
# In the event that the product being advertised includes an
# intact Zope distribution (with copyright and license included)
# then this clause is waived.
#
# 5. Names associated with Zope or Digital Creations must not be used to
# endorse or promote products derived from this software without
# prior written permission from Digital Creations.
#
# 6. Modified redistributions of any form whatsoever must retain
# the following acknowledgment:
#
# "This product includes software developed by Digital Creations
# for use in the Z Object Publishing Environment
# (http://www.zope.org/)."
#
# Intact (re-)distributions of any official Zope release do not
# require an external acknowledgement.
#
# 7. Modifications are encouraged but must be packaged separately as
# patches to official Zope releases. Distributions that do not
# clearly separate the patches from the original work must be clearly
# labeled as unofficial distributions. Modifications which do not
# carry the name Zope may be packaged in any form, as long as they
# conform to all of the clauses above.
#
#
# Disclaimer
#
# THIS SOFTWARE IS PROVIDED BY DIGITAL CREATIONS ``AS IS'' AND ANY
# EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL DIGITAL CREATIONS OR ITS
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
# USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
# OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
# SUCH DAMAGE.
#
#
# This software consists of contributions made by Digital Creations and
# many individuals on behalf of Digital Creations. Specific
# attributions are listed in the accompanying credits file.
#
##############################################################################
""" python vmstat for linux, requires linuxproc.py module """
__version__ = "1.0"
import linuxproc
import sys, time
HEIGHT = 24
DIGITS = {}
for d in "1234567890":
DIGITS[d] = 1
def showheader(timestamp):
head="%8s%28s%8s%12s%11s%12s" % ('procs','memory','swap','io','system',
'cpu')
thead = head +"%12s" % 'time'
print timestamp and thead or head
s = "%2s %2s %2s %6s %6s %6s %6s %3s %3s %5s %5s %4s %5s %3s %3s %3s"
items = (
'r','b','w','swpd','free','buff','cache','si','so','bi','bo','in',
'cs','us','sy','id'
)
print s % items
def meminfo(mem=None):
if not mem: mem = linuxproc.meminfo()
swpd = mem['swaptotal'] - mem['swapfree']
return swpd, mem['memfree'], mem['buffers'], mem['cached']
def getcpu(stat=None):
if not stat: stat = linuxproc.stat()
cpu = stat['cpu']
return cpu['user'], cpu['nice'], cpu['system'], cpu['idle']
def getswap(stat=None):
if not stat: stat = linuxproc.stat()
swap = stat['swap']
return swap['in'], swap['out']
def getpage(stat=None):
if not stat: stat = linuxproc.stat()
page = stat['page']
return page['in'], page['out']
def getall():
stat = linuxproc.stat()
d = {}
lr, lb, ls = map(lambda x: len(x), linuxproc.getrunners())
mswap, mfree, mbuf, mcache = meminfo()
swapin, swapout = getswap(stat)
pgin, pgout = getpage(stat)
intr = stat['intr']['interrupts']
ctxt = stat['ctxt']['context_switches']
cuse, cnice, csys, cidl = getcpu(stat)
loc = locals()
for name in ('lr', 'lb', 'ls', 'mswap', 'mfree', 'mbuf', 'mcache',
'swapin', 'swapout', 'pgin', 'pgout', 'intr', 'ctxt', 'cuse',
'cnice', 'csys', 'cidl'):
d[name] = loc[name]
return d
def main(headers, count, delay, timestamp):
i = 0
HZ = 100L
KB_PER_PAGE = 1
showheader(timestamp)
l = [None, None]
stat = l[0] = getall()
duse = stat['cuse'] + stat['cnice']
dsys = stat['csys']
didl = stat['cidl']
Div = duse + dsys + didl
divo2 = Div/2
fswapin = (stat['swapin'] * KB_PER_PAGE * HZ + divo2)/Div
fswapout = (stat['swapout'] * KB_PER_PAGE * HZ + divo2)/Div
fpgin = (stat['pgin'] * HZ + divo2)/Div
fpgout = (stat['pgout'] * HZ + divo2)/Div
fintr = (stat['intr'] * HZ + divo2)/Div
fctxt = (stat['ctxt'] * HZ + divo2)/Div
fcusr = (100L * duse + divo2)/Div
fcsys = (100L * dsys + divo2)/Div
fcidle = (100L * didl + divo2)/Div
flr = stat['lr'] - 1 # minus ourselves
flb = stat['lb']
fls = stat['ls']
fmswap = stat['mswap']
fmfree = stat['mfree']
fmbuf = stat['mbuf']
fmcache = stat['mcache']
output(
flr, flb, fls, fmswap, fmfree, fmbuf, fmcache, fswapin, fswapout,
fpgin, fpgout, fintr, fctxt, fcusr, fcsys, fcidle,
timestamp and time.asctime() or ''
)
# if we're repeating, do it below
tog = 0
i = 0
while 1:
i = i + 1
if not delay: break
if count and i == count: break
tog = not tog
time.sleep(delay)
if i % HEIGHT == 0 and headers:
showheader(timestamp)
stat = l[tog] = getall()
old = l[not tog]
duse = (stat['cuse']-old['cuse']) + (stat['cnice']-old['cnice'])
dsys = (stat['csys']-old['csys'])
didl = (stat['cidl']-old['cidl'])
# idle may run backwards (kernel "feature")
if didl < 0:
didl = 0
Div = duse + dsys + didl
divo2 = Div/2
pero2 = delay/2
flr = stat['lr'] - 1 # minus ourselves
flb = stat['lb']
fls = stat['ls']
fmswap = stat['mswap']
fmfree = stat['mfree']
fmbuf = stat['mbuf']
fmcache = stat['mcache']
fswapin = ((stat['swapin']-old['swapin']) *KB_PER_PAGE+pero2)/delay
fswapout = ((stat['swapout']-old['swapout']) *KB_PER_PAGE+pero2)/delay
fpgin = ((stat['pgin']-old['pgin']) +pero2)/delay
fpgout = ((stat['pgout']-old['pgout']) +pero2)/delay
fintr = ((stat['intr']-old['intr']) +pero2)/delay
fctxt = ((stat['ctxt']-old['ctxt']) +pero2)/delay
fcusr = (100L * duse + divo2)/Div
fcsys = (100L * dsys + divo2)/Div
fcidle = (100L * didl + divo2)/Div
output(
flr, flb, fls, fmswap, fmfree, fmbuf, fmcache, fswapin, fswapout,
fpgin, fpgout, fintr, fctxt, fcusr, fcsys, fcidle,
timestamp and time.asctime() or ''
)
def output(*args):
tfmt="%2u %2u %2u %6u %6u %6u %6u %3u %3u %5u %5u %4u %5u %3u %3u %3u %s"
fmt = tfmt[:-3]
if len(args) == 17:
print tfmt % args
elif len(args) == 16:
print fmt % args
def write_tstamp():
print time.asctime()
def usage():
print "usage: %s [-V] [-n] [-t] [delay [count]]" % sys.argv[0]
print " -V prints version."
print " -n causes the headers not to be reprinted regularly."
print " -t causes a timestamp to be printed."
print " delay is the delay between updates in seconds."
print " count is the number of updates."
if __name__ == '__main__':
delay_seen = None
headers = 1
timestamps = 0
count = 0
delay = 0
for arg in sys.argv[1:]:
if arg[0] != '-':
for char in arg:
if not DIGITS.has_key(char):
usage()
sys.exit(1)
if delay_seen:
count = int(arg)
else:
delay = int(arg)
delay_seen = 1
elif arg[1:] and arg[1] == 'V':
print sys.argv[0], 'version %s' % __version__
sys.exit(0)
elif arg[1:] and arg[1] == 'n':
headers = 0
elif arg[1:] and arg[1] == 't':
timestamps = 1
else:
usage()
sys.exit(1)
main(headers, count, delay, timestamps)