Open3 and background processes

I
thought there was a way to peek ahead on an IO object to see if any
data is available on the handle before attempting to read it

You're probably thinking of Kernel.select. To poll if data is available for
read on IO object foo, and read as much data is available, up to 1024 bytes
max:

  if select([foo], nil, nil, 0)
    res = foo.readpartial(1024)
  end

(select also returns true if the file is closed, in which case read will
return nil)

Beware of race conditions in your code - i.e. the child might not generate
output on stderr until some time later, so you may need to continue to poll
periodically.

This works, though I had to add a sleep call to give it time to pick
up an error:

require 'open3'
require 'timeout'

program = File.join(Dir.pwd, "miniserver.rb")

cmd = "ruby #{program} &"

Open3.popen3(cmd) do |stdin, stdout, stderr|
   sleep 0.1

   if select([stderr], nil, nil, 0)
      p stderr.readlines
   end
end

puts "Done"

This approach actually makes me less comfortable than my original
approach, however, because now I'll have to worry that I didn't sleep
long enough and an error will go unnoticed.

Regards,

Dan

···

On Aug 27, 2:22 am, Brian Candler <B.Cand...@pobox.com> wrote:

> I
> thought there was a way to peek ahead on an IO object to see if any
> data is available on the handle before attempting to read it

You're probably thinking of Kernel.select. To poll if data is available for
read on IO object foo, and read as much data is available, up to 1024 bytes
max:

if select([foo], nil, nil, 0)
res = foo.readpartial(1024)
end

(select also returns true if the file is closed, in which case read will
return nil)

Beware of race conditions in your code - i.e. the child might not generate
output on stderr until some time later, so you may need to continue to poll
periodically.