如何在Ruby中读取打开的文件

时间:2010-12-18 00:45:54

标签: ruby

我希望能够读取当前打开的文件。 test.rb将其输出发送到test.log,我希望能够阅读并最终通过电子邮件发送。

我使用cron运行它:

*/5 * * * /tmp/test.rb > /tmp/log/test.log 2>&1

我在test.rb中有这样的东西:

#!/usr/bin/ruby

def read_file(file_name)
  file = File.open(file_name, "r")
  data = file.read
  file.close
  return data
end

puts "Start"
puts read_file("/tmp/log/test.log")
puts "End"

当我运行此代码时,它只给出了这个输出:

Start

End

我希望输出是这样的:

Start
Start (from the reading of the test.log since it should have the word start already)
End

5 个答案:

答案 0 :(得分:41)

好的,你试图一次做几件事,我怀疑你没有系统地测试,然后再从一步走到下一步。

首先我们要清理你的代码:

def read_file(file_name)
  file = File.open(file_name, "r")
  data = file.read
  file.close
  return data
end

puts "Start"
puts read_file("/tmp/log/test.log")
puts "End"

可以替换为:

puts "Start"
puts File.read("./test.log")
puts "End"

简单明了;不需要方法或任何复杂的......但是。

请注意,为了便于测试,我正在使用当前目录中的文件。要在其中加入一些内容,我只会这样做:

echo "foo" > ./test.log

运行测试代码给了我......

Greg:Desktop greg$ ruby test.rb 
Start
foo
End

所以我知道代码正在正确阅读和打印。

现在我们可以在处理它的疯狂之前测试进入crontab的内容:

Greg:Desktop greg$ ruby test.rb > ./test.log 
Greg:Desktop greg$ 

嗯。没有输出。有些东西被破坏了。我们之前知道文件中有内容,所以发生了什么?

Greg:Desktop greg$ cat ./test.log 
Start

End

捕获文件显示它具有代码的“开始”和“结束”输出,但现在应该已经读取和输出的部分丢失了。

发生的事情是shell在将控制权传递给Ruby之前截断了“test.log”,然后Ruby打开并执行了代码,打开现在空的文件进行打印。换句话说,你要求shell在你读它之前截断(清空)它。

修复是从一个不同于你要写入的文件中读取,如果你试图对它的内容做一些事情。如果你不想对它的内容做些什么,那么用Ruby读取它就没有意义,只是把它写到另一个文件中:我们有cp和/或mv来做这些事情我们没有Ruby参与其中。所以,如果我们要对内容做些什么,这就更有意义了:

ruby test.rb > ./test.log.out

我将使用echo "foo" > ./test.log重置文件内容,并且它显示'foo',所以我准备再次尝试重定向测试:

Greg:Desktop greg$ ruby test.rb > ./test.log.out
Greg:Desktop greg$ cat test.log.out 
Start
foo
End

那个时候它起作用了。再次尝试它会产生相同的结果,所以我不会在这里显示结果。

如果您要通过电子邮件发送文件,此时可以添加该代码。使用对变量的赋值替换puts行中的puts File.read('./test.log')将存储文件的内容:

contents = File.read('./test.log')

然后,您可以使用contents作为电子邮件的正文。 (而且,不是使用Ruby来做所有这些,我可能会使用mailmailx或使用命令行和shell将它直接传递给sendmail,但这是你的调用。)

此时,使用与命令行上使用的命令相同的命令,可以将命令添加到crontab。因为它在cron中运行,并且我们想要了解错误,我们还会添加2>&1重定向来捕获STDERR,就像之前一样。请记住,您可以 NOT 写入您要读取的同一个文件,或者您将有一个空文件可供阅读。

这足以让你的应用运行起来。

答案 1 :(得分:17)

class FileLineRead
  File.open("file_line_read.txt") do |file|
    file.each do |line|
      phone_number = line.gsub(/\n/,'')
      user = User.find_by_phone_number(line)
      user.destroy unless user.nil?
    end
  end
end
  1. 打开文件
  2. 读取行
  3. DB Select
  4. 数据库更新

答案 2 :(得分:4)

在cron作业中,您已经打开并清除test.log(通过重定向),然后再在Ruby脚本中阅读它。

为什么不在Ruby中进行读写操作?

答案 3 :(得分:4)

可能是权限问题或文件可能不存在。

f = File.open("test","r")
puts f.read()
f.close()

以上将阅读文件测试。如果该文件存在于当前目录中

答案 4 :(得分:3)

正如我所看到的,问题是Slomojo已经解决了。我只会补充:
在Ruby中读取和打印文本文件,只需:

puts File.read("/tmp/log/test.log")