我想在ruby中做一件简单的事情:进入服务器,在日志文件上启动tailf -f
命令,并对输出流执行一些操作。 (比如提取一些信息)
我怎么能在ruby中做到?
如果使用反引号来执行命令,它的输出永远不会返回,是否有一个旧的连续输出的数据结构?
答案 0 :(得分:1)
最简单的方法(以及大多数Unix-y方式)是使用-n
命令的-p
或ruby
参数。从手册页(man ruby
):
-n Causes Ruby to assume the following loop around your script, which makes
it iterate over file name arguments somewhat like sed -n or awk.
while gets
...
end
这是模糊的(并且“文件名参数”位有误导性),所以这是一个例子(让我们称之为sum.rb
):
BEGIN {
sum = 0
}
sum += $_.to_i
END {
puts "Sum: #{sum}"
}
当我们使用ruby -n
运行此脚本时会发生什么情况,BEGIN
块中的代码将运行一次,然后块外的代码将针对通过管道传输给Ruby的每一行输入运行该行存储在$_
中 - 然后END
块中的代码将会运行。
假设我们有一个包含以下内容的文件(让我们称之为data.txt
):
10
15
25
50
现在我们可以这样做:
$ cat data.txt | ruby -n sum.rb
Sum: 100
如果我们只想总结前两个数字怎么办?使用head
!
$ head -2 data.txt | ruby -n sum.rb
Sum: 25
如果我们想打印除了总和之外的每个数字怎么办?使用-p
(代表“打印”)代替-n
:
$ head -2 data.txt | ruby -p sum.rb
10
15
Sum: 25
ruby
命令非常强大。例如,-a
选项将 a 将每行自动拆分为数组并将其放入$F
,因此如果您的输入有两列,则每行的第一列将在$F[0]
,$F[1]
中的第二个,依此类推。我强烈建议您输入man ruby
并花几分钟时间查看可用的选项。这是一篇很好的博客文章,其中介绍了一些功能:http://arjanvandergaag.nl/blog/using-ruby-command-line-options.html
最后一件事:为了便于使用,我建议在脚本顶部添加一个shebang行,例如:
#!/usr/bin/env ruby -n
...然后使用chmod
使您的脚本可执行(例如chmod ug+x sum.rb
)。通过这种方式,您的脚本可以指定所需的所有参数,您只需执行cat data.txt | ./sum.rb
。
答案 1 :(得分:0)
您可以使用pty模块。
你需要做这样的事情:
require 'pty'
cmd = "tail -f <path-to-your-log-file>"
begin
PTY.spawn(cmd) do |stdout, stdin, pid|
begin
# print output to show how it works
# you will need to extract your info from "line" variable below
stdout.each { |line| print line }
rescue Errno::EIO
puts "This means the process has finished giving output"
end
end
rescue PTY::ChildExited
puts "Child process exited!"
end
答案 2 :(得分:0)
f=File.open("path_to_log_file")
no_of_lines_per_fetch = 1
f.seek(0, no_of_lines_per_fetch)
def decision_making_function(data)
#your logic
puts "processing #{data}"
end
while true
if (line=f.gets) != nil
decision_making_function(line)
end
end