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
5 answers
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 temoscp
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.)
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
- abrir um ficheiro
- Leia a Linha
- DB Select
- Actualização do DB
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?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
para ler e imprimir um ficheiro de texto em Ruby, basta:
puts File.read("/tmp/log/test.log")