IO.popen - continuous output

A

Andy Koch

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 Koch
 
S

Sebastian Hungerecker

Andy said:
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.
 
D

Dan Zwell

Sebastian said:
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
 
D

Dan Zwell

Dan said:
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
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
 
S

Sebastian Hungerecker

Dan said:
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.

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

Dan Zwell

Sebastian said:
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.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
474,262
Messages
2,571,311
Members
47,986
Latest member
ColbyG935

Latest Threads

Top