Como ler um ficheiro aberto em Ruby

quero ser capaz de ler um ficheiro aberto de momento. Teste.o rb está a enviar a sua saída para o teste.log que eu quero ser capaz de ler e, em última análise, enviar por e-mail.

estou a fazer isto usando cron:

*/5 * * * /tmp/test.rb > /tmp/log/test.log 2>&1
Tenho algo assim no teste.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"

Quando eu executar este código, ele só me dá esta saída:

Start

End

eu esperaria que a saída fosse algo como isto:

Start
Start (from the reading of the test.log since it should have the word start already)
End
 20
Author: the Tin Man, 2010-12-18

5 answers

Está a tentar fazer várias coisas ao mesmo tempo, e suspeito que não fez testes sistemáticos antes de passar de um passo para o outro. Primeiro vamos limpar o seu código.
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"

Pode ser substituído por:

puts "Start"
puts File.read("./test.log")
puts "End"
É simples e simples, não há necessidade de um método ou algo complicado... ainda.

Repare que, para facilitar os testes, estou a trabalhar com um ficheiro no directório actual. Para colocar algum conteúdo nele eu simplesmente vou do:

echo "foo" > ./test.log
Executar o código de teste dá-me...
Greg:Desktop greg$ ruby test.rb 
Start
foo
End
Então, sei que o código está a ler e a imprimir correctamente. Agora podemos testar o que entraria no crontab, antes de lidarmos com a sua loucura.
Greg:Desktop greg$ ruby test.rb > ./test.log 
Greg:Desktop greg$ 
Hmm. Sem saída. Algo está quebrado com isso. Sabíamos que havia conteúdo no arquivo anteriormente, então o que aconteceu?
Greg:Desktop greg$ cat ./test.log 
Start

End

Cat'ing the file shows it has the "Start" and " End " output of the code, but the part that should have been read and falta a saída.

O que se passa é que a concha truncou o teste.log " pouco antes de passar o controle para Ruby, que então abriu e executou o código, que abriu o arquivo agora vazio para imprimi-lo. Em outras palavras, você está pedindo à shell para truncá-lo (vazio) pouco antes de lê-lo. A solução é ler de um arquivo diferente do que você vai escrever, se você está tentando fazer algo com o conteúdo dele. Se não estás a tentar fazer alguma coisa com o conteúdo então não há nenhum ponto em lê-lo com Ruby apenas para escrevê-lo em um arquivo diferente: nós temos cp e/ou mv para fazer essas coisas para nós witout Ruby estar envolvido. Então, isso faz mais sentido se vamos fazer algo com o conteúdo:
ruby test.rb > ./test.log.out

Vou reiniciar o conteúdo do ficheiro usando {[[11]}, e cat'ing mostrou 'foo', por isso estou pronto para tentar o teste de redireccionamento novamente:

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

Daquela vez que funcionou. Tentar novamente tem o mesmo resultado, então eu não vou mostrar os resultados aqui.

Se você vai enviar e-mail para o arquivo você poderia adicionar esse código neste momento. A substituição do puts na linha puts File.read('./test.log') por uma atribuição a uma variável irá guardar o conteúdo do ficheiro:

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

Então você pode usar contents como o corpo de um e-mail. (E, em vez de usar Ruby para tudo isso eu provavelmente fazê-lo usando mail ou mailx ou canalizá-lo diretamente para o sendmail, usando a linha de comando e shell, mas essa é a sua chamada.)

Neste momento, as coisas estão numa boa posição para ... adicione o comando ao crontab, usando o mesmo comando usado na linha de comandos. Porque ele está rodando em cron, e erros podem acontecer que gostaríamos de saber, nós adicionamos o redirecionamento para capturar STDERR também, assim como você fez antes. Lembre-se apenas que você pode Não escrever para o mesmo arquivo que você vai ler ou você terá um arquivo vazio para ler. É o suficiente para pôr a aplicação a funcionar.
 38
Author: the Tin Man, 2010-12-18 20:49:47
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. abrir um ficheiro
  2. Leia a Linha
  3. DB Select
  4. Actualização do DB
 17
Author: Jini Kim, 2011-09-19 04:57:29

Na tarefa cron, você já abriu e limpou {[[0]} (através de redireccionamento) antes de a ler no programa Ruby.

Porque não lês e escreves em Ruby?
 4
Author: ocodo, 2010-12-18 00:50:46

Pode ser um problema de permissões ou o ficheiro pode não existir.

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

O acima irá ler o teste do ficheiro. Se o ficheiro existir na pasta actual

 4
Author: EnabrenTane, 2010-12-18 15:04:04
O problema, Como posso ver, já está resolvido pelo Slomojo. Só vou acrescentar:
para ler e imprimir um ficheiro de texto em Ruby, basta:
puts File.read("/tmp/log/test.log")
 3
Author: Nakilon, 2010-12-18 00:57:01