forked from ywangd/stash
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathtail.py
137 lines (113 loc) · 3.61 KB
/
tail.py
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
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
# -*- coding: utf-8 -*-
"""Print the last 10 lines of the given files.
"""
from __future__ import print_function
import argparse
import time
import sys
import fileinput
def tail_f(f, wait_sec):
while True:
l = f.readline()
if l:
yield l
else:
# print('!!READ NOTHING!!')
time.sleep(wait_sec)
_first_file = True
def write_header(fname):
global _first_file
header_fmt = '{}==> {} <==\n'
print(header_fmt.format('' if _first_file else '\n', fname), end='')
_first_file = False
def main(args):
p = argparse.ArgumentParser(description=__doc__)
p.add_argument(
"-c",
"--bytes",
default="",
type=str,
metavar='K',
help="""output the last K bytes; or -c +K starting with the Kth"""
)
p.add_argument("-f", "--follow", action="store_true", help="""follow specified files""")
p.add_argument(
"-n",
"--lines",
default="10",
type=str,
metavar='K',
help="""print the last K lines instead of 10;
or use -n +K to print lines starting with the Kth"""
)
p.add_argument("-q", "--quiet", "--silent", action='store_true', help="never print headers for each file")
p.add_argument("-v", "--verbose", action='store_true', help="always print headers for each file")
p.add_argument(
"-s",
"--sleep-interval",
type=float,
default=1.0,
help="with -f, sleep for approximately N seconds (default 1.0) between iterations."
)
p.add_argument("files", action="store", nargs="*", help="files to print")
ns = p.parse_args(args)
status = 0
if len(ns.files) == 0:
ns.files = ['-']
if ns.follow and '-' in ns.files:
print('tail: warning: following stdin indefinitely is ineffective')
if ns.bytes:
use_bytes = True
if ns.bytes[0] == '+':
from_start = True
else:
from_start = False
count = abs(int(ns.bytes)) # '-n -3' is equivalent to '-n 3'
else:
use_bytes = False
if ns.lines[0] == '+':
from_start = True
else:
from_start = False
count = abs(int(ns.lines)) # '-n -3' is equivalent to '-n 3'
try:
for i, fname in enumerate(ns.files):
if ns.verbose or (len(ns.files) > 1 and not ns.quiet):
write_header(fname if fname != '-' else 'standard input')
try:
if fname == '-':
f = sys.stdin
else:
f = open(fname)
buf = []
j = -1
while True:
j += 1
if use_bytes:
l = f.read(1)
else:
l = f.readline()
if not l:
break
buf.append(l)
if from_start:
if j >= count - 1: break
elif len(buf) > count:
del buf[0]
for item in buf:
print(item, end='')
if i == len(ns.files) - 1 and ns.follow:
for l in tail_f(f, ns.sleep_interval):
print(l, end='')
sys.stdout.flush()
finally:
if fname != '-':
f.close()
except Exception as e:
print('tail :%s' % str(e))
status = 1
finally:
fileinput.close()
sys.exit(status)
if __name__ == "__main__":
main(sys.argv[1:])