blob: 93372c5d9a0e9ba7701a21d0304ca29a87fd34fc [file] [log] [blame]
Guido van Rossum2b287762001-01-05 20:54:07 +00001#! /usr/bin/env python
2
Guido van Rossum8161a652007-11-12 23:12:57 +00003"""repeat [-i SECONDS] <shell-command>
Guido van Rossum2b287762001-01-05 20:54:07 +00004
Thomas Wouters73e5a5b2006-06-08 15:35:45 +00005This simple program repeatedly (at 1-second intervals) executes the
Guido van Rossum2b287762001-01-05 20:54:07 +00006shell command given on the command line and displays the output (or as
7much of it as fits on the screen). It uses curses to paint each new
8output on top of the old output, so that if nothing changes, the
9screen doesn't change. This is handy to watch for changes in e.g. a
10directory or process listing.
11
Guido van Rossum8161a652007-11-12 23:12:57 +000012The -i option lets you override the sleep time between executions.
13
Guido van Rossum2b287762001-01-05 20:54:07 +000014To end, hit Control-C.
15"""
16
17# Author: Guido van Rossum
18
19# Disclaimer: there's a Linux program named 'watch' that does the same
20# thing. Honestly, I didn't know of its existence when I wrote this!
21
22# To do: add features until it has the same functionality as watch(1);
23# then compare code size and development time.
24
25import os
26import sys
27import time
28import curses
Guido van Rossum8161a652007-11-12 23:12:57 +000029import getopt
Guido van Rossum2b287762001-01-05 20:54:07 +000030
31def main():
Guido van Rossum8161a652007-11-12 23:12:57 +000032 interval = 1.0
33 try:
34 opts, args = getopt.getopt(sys.argv[1:], "hi:")
35 except getopt.error as err:
36 print(err, file=sys.stderr)
37 sys.exit(2)
38 if not args:
Collin Winter6f2df4d2007-07-17 20:59:35 +000039 print(__doc__)
Guido van Rossum2b287762001-01-05 20:54:07 +000040 sys.exit(0)
Guido van Rossum8161a652007-11-12 23:12:57 +000041 for opt, arg in opts:
42 if opt == "-i":
43 interval = float(arg)
44 if opt == "-h":
45 print(__doc__)
46 sys.exit(0)
47 cmd = " ".join(args)
48 cmd_really = cmd + " 2>&1"
49 p = os.popen(cmd_really, "r")
Guido van Rossum2b287762001-01-05 20:54:07 +000050 text = p.read()
51 sts = p.close()
Guido van Rossum8161a652007-11-12 23:12:57 +000052 text = addsts(interval, cmd, text, sts)
Guido van Rossum2b287762001-01-05 20:54:07 +000053 w = curses.initscr()
54 try:
Thomas Wouters73e5a5b2006-06-08 15:35:45 +000055 while True:
Guido van Rossum2b287762001-01-05 20:54:07 +000056 w.erase()
57 try:
58 w.addstr(text)
59 except curses.error:
60 pass
61 w.refresh()
Guido van Rossum8161a652007-11-12 23:12:57 +000062 time.sleep(interval)
63 p = os.popen(cmd_really, "r")
Guido van Rossum2b287762001-01-05 20:54:07 +000064 text = p.read()
65 sts = p.close()
Guido van Rossum8161a652007-11-12 23:12:57 +000066 text = addsts(interval, cmd, text, sts)
Guido van Rossum2b287762001-01-05 20:54:07 +000067 finally:
68 curses.endwin()
69
Guido van Rossum8161a652007-11-12 23:12:57 +000070def addsts(interval, cmd, text, sts):
71 now = time.strftime("%H:%M:%S")
72 text = "%s, every %g sec: %s\n%s" % (now, interval, cmd, text)
73 if sts:
74 msg = "Exit status: %d; signal: %d" % (sts>>8, sts&0xFF)
75 if text and not text.endswith("\n"):
76 msg = "\n" + msg
77 text += msg
78 return text
79
Guido van Rossum2b287762001-01-05 20:54:07 +000080main()