From: Robert Klemme Date: 2012-11-08T01:58:28+09:00 Subject: Re: streaming stdout with open4 to prevent parent/child buffer lock --90e6ba10b07d94685904cdeaa02f Content-Type: text/plain; charset=ISO-8859-1 On Thu, Nov 1, 2012 at 10:06 PM, Matthew Purdy wrote: > i have to fork a process and read a large amount of stdout; however, the > child buffer gets filled up and everything hangs. how do you read > stdout as stream? > > the only way i know how to do this is the following two ways; but both > do not work; how can you get the stdout when the method starts so you > can read stdout as it get written to from the child process? > > You can use a thread: $ ruby x.rb 1 2 3 4 5 6 7 8 9 10 $ cat -n x.rb 1 2 3 require 'open3' 4 5 Open3.popen3("seq", "1", "10") do |s_in, s_out, s_err, th| 6 # eat stderr 7 th_err = Thread.new { s = nil; while s_err.read(1024, s); end } 8 9 # copy stdout 10 s_out.each_line {|line| puts line} 11 12 # wait until finished 13 th_err.join 14 end 15 Kind regards robert -- remember.guy do |as, often| as.you_can - without end http://blog.rubybestpractices.com/ --90e6ba10b07d94685904cdeaa02f Content-Type: text/html; charset=ISO-8859-1 Content-Transfer-Encoding: quoted-printable


On Thu, N= ov 1, 2012 at 10:06 PM, Matthew Purdy <lists@ruby-forum.com> wrote:
i have to fork a process = and read a large amount of stdout; however, the
child buffer gets filled up and everything hangs. =A0how do you read
stdout as stream?

the only way i know how to do this is the following two ways; but both
do not work; how can you get the stdout when the method starts so you
can read stdout as it get written to from the child process?


You can use a thread:

$ ruby x.rb
1
= 2
3
4
5
6
7
8
9
10
$ cat -n x.rb
=A0=A0=A0=A0= 1
=A0=A0=A0=A0 2
=A0=A0=A0=A0 3=A0 require 'open3'
=A0=A0= =A0=A0 4
=A0=A0=A0=A0 5=A0 Open3.popen3("seq", "1", = "10") do |s_in, s_out, s_err, th|
=A0=A0=A0=A0 6=A0=A0=A0 # eat stderr
=A0=A0=A0=A0 7=A0=A0=A0 th_err =3D = Thread.new { s =3D nil; while s_err.read(1024, s); end }
=A0=A0=A0=A0 8<= br>=A0=A0=A0=A0 9=A0=A0=A0 # copy stdout
=A0=A0=A0 10=A0=A0=A0 s_out.eac= h_line {|line| puts line}
=A0=A0=A0 11
=A0=A0=A0 12=A0=A0=A0 # wait u= ntil finished
=A0=A0=A0 13=A0=A0=A0 th_err.join
=A0=A0=A0 14=A0 end
=A0=A0=A0 15
Kind regards

robert

--
rem= ember.guy do |as, often| as.you_can - without end
http://blog.rubybestpractices.com/
--90e6ba10b07d94685904cdeaa02f--