Подтвердить что ты не робот

Как читать открытый файл в 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
4b9b3361

Ответ 1

Хорошо, вы пытаетесь сделать несколько вещей сразу, и я подозреваю, что вы не систематически тестировали, прежде чем переходить с одного шага на другой.

Сначала мы очистим ваш код:

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

поэтому я знаю, что код правильно читает и печатает.

Теперь мы можем проверить, что войдет в кронтаб, прежде чем мы справимся с его безумием:

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

Хм. Нет выхода. Что-то с этим сломалось. Мы знали, что ранее было содержимое в файле, и что произошло?

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

End

Показ файла показывает, что он имеет выходные данные "Start" и "End", но часть, которая должна была быть прочитана и выведена, теперь отсутствует.

Что происходит, так это то, что оболочка обрезала "test.log" перед тем, как передать управление Ruby, который затем открыл и выполнил код, который открыл пустой файл для его печати. Другими словами, вы просите оболочку обрезать (пусто) ее непосредственно перед ее чтением.

Исправление состоит в том, чтобы читать из другого файла, чем вы собираетесь писать, если вы пытаетесь что-то сделать с его содержимым. Если вы не пытаетесь что-то сделать с его содержимым, тогда нет смысла читать его с помощью Ruby, чтобы записать его в другой файл: у нас есть cp и/или mv, чтобы сделать это для нас без Ruby участвует. Таким образом, это имеет смысл, если мы собираемся что-то сделать с содержимым:

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

Я reset содержимое файла, используя echo "foo" > ./test.log, и cat'ing он показал "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 для всего этого, я бы, вероятно, сделал это с помощью mail или mailx или напрямую подключил его к sendmail, используя командную строку и оболочку, но это ваш вызов.)

В этот момент все в порядке, чтобы добавить команду в crontab, используя ту же команду, что и в командной строке. Поскольку он работает в cron и могут возникнуть ошибки, о которых мы хотели бы узнать, мы добавили перенаправление 2>&1 для захвата STDERR также, как и раньше. Просто помните, что вы НЕ можете писать в тот же файл, который собираетесь читать, или у вас будет пустой файл для чтения.

Это достаточно, чтобы ваше приложение работало.

Ответ 2

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
  • открыть файл
  • строка чтения
  • DB Выберите
  • Обновление базы данных

Ответ 3

В задании cron вы уже открыли и очистили test.log (через перенаправление), прежде чем прочитать его в Ruby script.

Почему бы и не читать и писать в Ruby?

Ответ 4

Проблема, как я вижу, уже решена Сломоджо. Добавлю только:
для чтения и печати текстового файла в Ruby, просто:

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

Ответ 5

Это может быть проблема с разрешениями или файл может не существовать.

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

Вышеприведенное будет читать тест файла. Если файл существует в текущем каталоге