小智 17
def watch_for(file, pattern)
f = File.open(file,"r")
f.seek(0,IO::SEEK_END)
while true do
select([f])
line = f.gets
puts "Found it! #{line}" if line=~pattern
end
end
watch_for("g.txt",/ERROR/)
Run Code Online (Sandbox Code Playgroud)
感谢ezpz的想法,使用select方法,你得到你想要的.select方法正在侦听IO的流,读取"迟到"的字节.
您可以通过Kernel#select以下方式使用:
def watch_for(file,pattern)
f = File.open(file,"r")
# Since this file exists and is growing, seek to the end of the most recent entry
f.seek(0,IO::SEEK_END)
while true
select([f])
puts "Found it!" if f.gets =~ pattern
end
end
Run Code Online (Sandbox Code Playgroud)
然后称之为:
watch_for("some_file", /ERROR/)
Run Code Online (Sandbox Code Playgroud)
我已经省略了所有错误检查等等 - 你会想要这个以及可能有一些机制来摆脱循环.但基本的想法是存在的.
有两种方法:
sleep置于无限循环内是好的)这是我写的一篇文章:Ruby for Admins:阅读成长文件.因此,结合事件子系统和轮询的程序如下所示:
def tail_dash_f(filename)
open(ARGV.first) do |file|
file.read
case RUBY_PLATFORM # string with OS name, like "amd64-freebsd8"
when /bsd/, /darwin/
require 'rb-kqueue'
queue = KQueue::Queue.new
queue.watch_file(ARGV.first, :extend) do
yield file.read
end
queue.run
when /linux/
require 'rb-inotify'
queue = INotify::Notifier.new
queue.watch(ARGV.first, :modify) do
yield file.read
end
queue.run
else
loop do
changes = file.read
unless changes.empty?
yield changes
end
sleep 1.0
end
end
end
end
tail_dash_f ARGV.first do |data|
print data
if data =~ /error/i
# do something else, for example send an email to administrator
end
end
Run Code Online (Sandbox Code Playgroud)
如果你在Linux上...
tail -f log/development.log | grep "ERROR"
Run Code Online (Sandbox Code Playgroud)
除非你真的希望它出于某种原因成为Ruby脚本.