IO.popen - continuous output

Hi,

is it possible to get a continuous output stream with IO.popen(‘xxx’)

example,

IO.popen(‘tail -f some_log_file’)…

where the goal is to see the tail output as it’s generating, rather than
waiting for the process to complete to dump the generated output.

Thank You,

Andy K.

On 7/19/07, Andy K. [email protected] wrote:

waiting for the process to complete to dump the generated output.
I know this is possible with EventMachine’s version of popen. If no one
else
comes up with a standard way to do it, look at EventMachine.

Andy K. wrote:

Hi,

is it possible to get a continuous output stream with IO.popen(‘xxx’)

example,

IO.popen(‘tail -f some_log_file’)…

where the goal is to see the tail output as it’s generating, rather than
waiting for the process to complete to dump the generated output.

That is what you get with IO.popen.
For example,
IO.popen(‘tail -f testfile’).each_line do |line|
puts line.upcase
end
prints out the upcased version of any line added to testfile as soon as
it is
added to the file.

Sebastian H. wrote:

That is what you get with IO.popen.
For example,
IO.popen(‘tail -f testfile’).each_line do |line|
puts line.upcase
end
prints out the upcased version of any line added to testfile as soon as it is
added to the file.

I was just wondering about this, and I see that you are correct,
usually–this is very strange.

file1:
#!/usr/bin/env ruby
5.times {puts “hi”; sleep 0.5}

file2:
#!/usr/bin/env ruby
IO.popen("./file1").each_line { |line| puts line }

When running file2 (which should stream the output from file1), the
output is not streamed, but instead saved up until “file1” finishes
running and then dumped. Note that this only occurs when file1 is a ruby
file–replacing it with a bash script that does the same thing causes
the output to stream properly. I am perplexed. Any insight? (Is this a
bug?)

I’m using ruby 1.8.5 on linux.

Dan

Dan Z. wrote:

IO.popen("./file1").each_line { |line| puts line }
Dan

I’ve made this a bit more accessible for the non-linux folks:
In IRB, try running thes one-liner (with wide margins):
IO.popen(“ruby -e ‘5.times {|n| puts n; sleep 1}’”).each_line {|line|
puts line}

It should print a number every second, right? Well, it doesn’t for me…

Dan

Dan Z. wrote:

running and then dumped.
That seems to be a buffering issue. If you set STDOUT.sync to true in
file1,
it will work as expected.

Sebastian H. wrote:

When running file2 (which should stream the output from file1), the
output is not streamed, but instead saved up until “file1” finishes
running and then dumped.

That seems to be a buffering issue. If you set STDOUT.sync to true in file1,
it will work as expected.

Thanks, that’s good to know. Having this behavior unexplained made me a
bit nervous about using IO.popen.