1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89
|
import os
import sys
import time
from optparse import OptionParser
def tail_lines(fd, linesback = 10, avgcharsperline=75):
# Contributed to Python Cookbook by Ed Pascoe (2003)
while 1:
try:
fd.seek(-1 * avgcharsperline * linesback, 2)
except IOError:
fd.seek(0)
if fd.tell() == 0:
atstart = 1
else:
atstart = 0
lines = fd.read().split("\n")
if (len(lines) > (linesback+1)) or atstart:
break
avgcharsperline=avgcharsperline * 1.3
if len(lines) > linesback:
start = len(lines) - linesback - 1
else:
start = 0
return lines[start:len(lines)-1]
def reduce_files_to_tail(files, linesback=10, avgcharsperline=75):
if isinstance(files, str):
files = [files]
for fname in files:
fd = open(fname, 'r')
lines = tail_lines(fd, linesback, avgcharsperline)
lines = [line + '\n' for line in lines]
fd.close()
print "Writing %d lines to %s" % (linesback, fname)
fd = open(fname, 'w')
fd.writelines(lines)
fd.close()
def handle_line(line):
print line,
def do_tail(filename, lines, follow, func = handle_line):
fd = open(filename, 'r')
for line in tail_lines(fd, lines):
func(line + "\n")
if not follow:
return
while 1:
where = fd.tell()
line = fd.readline()
if not line:
fd_results = os.fstat(fd.fileno())
try:
st_results = os.stat(filename)
except OSError:
st_results = fd_results
if st_results[1] == fd_results[1]:
time.sleep(1)
fd.seek(where)
else:
print "%s changed inode numbers from %d to %d" % (filename, fd_results[1], st_results[1])
fd = open(filename, 'r')
else:
func(line)
def main(argv = sys.argv):
parser = OptionParser()
parser.add_option("-n", "--number", action="store", type="int", dest = "number", default=10)
parser.add_option("-f", "--follow", action="store_true", dest = "follow", default=0)
(options, args) = parser.parse_args()
do_tail(args[0], options.number, options.follow, handle_line)
if __name__ == "__main__":
try:
main(sys.argv)
except KeyboardInterrupt:
pass
|