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

Car*_*men 23 ruby

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

我使用cron运行它:

*/5 * * * /tmp/test.rb > /tmp/log/test.log 2>&1
Run Code Online (Sandbox Code Playgroud)

我在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"
Run Code Online (Sandbox Code Playgroud)

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

Start

End
Run Code Online (Sandbox Code Playgroud)

我希望输出是这样的:

Start
Start (from the reading of the test.log since it should have the word start already)
End
Run Code Online (Sandbox Code Playgroud)

the*_*Man 42

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

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

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"
Run Code Online (Sandbox Code Playgroud)

可以替换为:

puts "Start"
puts File.read("./test.log")
puts "End"
Run Code Online (Sandbox Code Playgroud)

它简单明了; 现在不需要一种方法或任何复杂的东西......

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

echo "foo" > ./test.log
Run Code Online (Sandbox Code Playgroud)

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

Greg:Desktop greg$ ruby test.rb 
Start
foo
End
Run Code Online (Sandbox Code Playgroud)

所以我知道代码正在读取和正确打印.

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

Greg:Desktop greg$ ruby test.rb > ./test.log 
Greg:Desktop greg$ 
Run Code Online (Sandbox Code Playgroud)

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

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

End
Run Code Online (Sandbox Code Playgroud)

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

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

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

ruby test.rb > ./test.log.out
Run Code Online (Sandbox Code Playgroud)

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

Greg:Desktop greg$ ruby test.rb > ./test.log.out
Greg:Desktop greg$ cat test.log.out 
Start
foo
End
Run Code Online (Sandbox Code Playgroud)

那个时候它奏效了.再次尝试它有相同的结果,所以我不会在这里显示结果.

如果您要通过电子邮件发送文件,则可以在此时添加该代码.更换putsputs File.read('./test.log')线与赋值给一个变量将存储文件的内容:

contents = File.read('./test.log')
Run Code Online (Sandbox Code Playgroud)

然后,您可以使用contents电子邮件的正文.(并且,不是使用Ruby来做所有这些,我可能会使用mail或者mailx使用命令行和shell将它直接传递给sendmail,但这是你的电话.)

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

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


小智 19

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
Run Code Online (Sandbox Code Playgroud)
  1. 打开文件
  2. 读线
  3. 数据库选择
  4. 数据库更新


oco*_*odo 5

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

为什么不在 Ruby 中同时进行读写?


Ena*_*ane 5

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

f = File.open("test","r")
puts f.read()
f.close()
Run Code Online (Sandbox Code Playgroud)

以上将读取文件test。如果文件存在于当前目录