From: Curt Sampson [mailto:cjs@cynic.net]
- Check for rotation by checking for changes in
the inode number
…
That’s true, you just have to stat the actual filename everytime and
check against the current filehandle.Right. You also ought to check the device number, in case the file
is somewhow moved to another device and ends up with the same inode
number. At least, that’s what I did when I added the ‘-F’ option
to tail(1) in NetBSD. Maybe I’m just anal-retentive.
Heh. I came across that while reading some usenet posts on a similar
subject.
Also, you might want to check to see if the file has been shortened,
in case the writer truncates it and starts writing again at the
beginning.
Wow. Thorough.
Well, here’s what I had come up with so far, using one of Paul Brannan’s
posts as a starting point. Between all of us, we should have something
pretty good and thorough soon.
class Tail < File
def initialize(file,sleeptime=10)
@file = File.open(file,“r”)
@sleeptime = sleeptime
end
···
-----Original Message-----
On Thu, 1 Aug 2002, James F.Hranicky wrote:On Thu, 1 Aug 2002 21:23:09 +0900 > > “Berger, Daniel” djberge@qwest.com wrote:
##############################################################
In block form, read a line at a time in a loop. Otherwise,
just return the number of lines specified as an array.
##############################################################
def tail(max=10)
if block_given?
yield get_lines(max)
loop do
line = @file.gets
yield line unless line.nil?
if @file.eof?
@file.seek(@file.pos)
end
sleep @sleeptime
end
else
get_lines(max)
end
end
#######################################################################
Grab the last ‘max’ lines (default is 10). This method was created
for two reasons. First, even a “tail -f” reads the last 10 lines.
Second, it’s separated from the tail() method in the event the
programmer just wants a “plain” tail.
#######################################################################
def get_lines(max)
@file.seek(0,IO::SEEK_END)
newline_count = 0
while newline_count < max
begin
@file.pos -= 2
rescue Errno::EINVAL
break
end
break if @file.eof?
if @file.getc.chr == "\n"
newline_count += 1
end
end
@file.readlines
end
end
=begin
= Description
Tail - A pure-Ruby implementation of the ‘tail’ command. Tail is a
subclass of File.
= Overview
t = Tail.new(“somefile.txt”)
To imitate ‘tail -f’, use a block
t.tail do |line|
puts line
end
To simply grab the last X lines, don’t use a block
a = t.tail(20)
puts a
or even
t.tail(20).each{ |line| puts line }
=end