我希望有一个ruby程序(rake任务)观察另一个rake任务的输出。输出写入器输出到stderr。我想阅读这些内容。我很难设置它。如果我有一个不断打印东西的作家(stdout_writer.rb):
#!/usr/bin/env ruby
puts 'writing...'
while true
$stdout.puts '~'
sleep 1
end
和一个读取它并回显的文件(stdin_reader.rb):
#!/usr/bin/env ruby
puts 'reading...'
while input = ARGF.gets
puts input
input.each_line do |line|
begin
$stdout.puts "got line #{line}"
rescue Errno::EPIPE
exit(74)
end
end
end
我试图让它们一起工作,没有任何反应:
$ ./stdout_writer.rb 2>&1 | ./stdin_reader.rb
$ ./stdout_writer.rb | ./stdin_reader.rb
没什么......虽然如果我只是回应到stdin_reader.rb,我得到了我期望的结果:
piousbox@e7440:~/projects/opera_events/sendgrid-example-operaevent$ echo "ok true" | ./stdin_reader.rb
reading...
ok true
got line ok true
piousbox@e7440:~/projects/opera_events/sendgrid-example-operaevent$
那么我如何设置一个脚本,将stderr管道传入其中,以便它可以逐行读取?附加信息:这将是一个ubuntu upstart服务script1.rb | script2.rb
,其中script1发送消息,script2验证消息是由script1发送的
答案 0 :(得分:2)
来自stdout_writer.rb
的输出由Ruby缓存,因此读者进程看不到它。如果你等待足够长的时间,你应该看到结果以块的形式出现。
您可以在stdout_writer.rb开头的$stdout
上关闭缓存并获得setting sync
to true期望的结果:
$stdout.sync = true
答案 1 :(得分:1)
问题似乎是,当stdout_writer
无限运行时,stdin_reader
永远不会有机会从STDOUT
读取stdout_writer
作为管道,在这种情况下,正在等待stdout_writer
在stdin_reader
开始阅读之前完成。我通过将while true
更改为5.times do
来对此进行了测试。如果你这样做,等待5秒,./stdout_writer.rb | ./stdin_reader.rb
的结果是
reading...
writing...
got line writing...
~
got line ~
~
got line ~
~
got line ~
~
got line ~
~
got line ~
这不是您的代码本身的问题,但更多的问题是ruby执行在STDOUT | STDIN
处理方面有效。
另外,我并不认为我学到了研究这个问题所学到的东西。谢谢你的有趣运动。