From: Robert Klemme Date: 2009-03-20T23:17:15+09:00 Subject: Re: Wrapping applications in Ruby On 19.03.2009 22:00, Jp Hastings-spital wrote: > Robert, > Thanks very much for your reply - its helped no end! However I'm still > having problems: > > Firstly (though really this isn't vitally important, as I only *need* > stdout): > Open3.popen3 doesn't appear to work when I drop it in place of IO.popen > (where |stdout| is replaced with |stdin,stdout,stderr|). > The called program is definitely running, however even the following > code outputs nothing: > > Open3.popen3 "./counting.rb" do |stdin,stdout,stderr| > p stdout.read > end No idea what you're doing, but it works for me robert@fussel /c/Temp $ ./run-counter.rb Got 0 Got 10 Got 20 Got 30 Got 40 Got 50 Got 60 Got 70 Got 80 Got 90 Got 100 Got3 0 Got3 10 Got3 20 Got3 30 Got3 40 Got3 50 Got3 60 Got3 70 Got3 80 Got3 90 Got3 100 robert@fussel /c/Temp $ cat run-counter.rb #!/usr/bin/env ruby19 require 'open3' IO.popen "./counting.rb" do |io| io.each do |line| pct = line[%r{:\s*(\d+)%}, 1].to_i puts "Got #{pct}" end end Open3.popen3 "./counting.rb" do |sin,sout,serr| sin.close th = Thread.new { serr.read } sout.each do |line| pct = line[%r{:\s*(\d+)%}, 1].to_i puts "Got3 #{pct}" end th.join end robert@fussel /c/Temp $ > But as I say, I only really need the stdout pipe. The problem here is > that the program I'm calling doesn't appear to send the \n character at > all (its the output from HandBrake's CLI), and as such the io block only > gets called once, at the end of the program's execution. Here's some > code: > > $ HandBrakeCLI {options} 2> /dev/null > \rEncoding: task 1 of 1, 0.09 %\rEncoding: task 1 of 1, 0.13 > %\rEncoding: task 1 of 1, 0.18 %\rEncoding: task 1 of 1, 0.23 % > > $ cat wrapper.rb > input = "input.avi" > output = "output.mp4" > IO.popen("/usr/local/bin/HandBrakeCLI -i \"#{input}\" -o \"#{output}\"") > { |stdout| > p stdout.read > } > > This prints nothing! Am I right in thinking that the popen block gets > called every time a \n character is captured by the pipe? No. The block is called once per execution of the other process. > (Your > 'counting.rb' uses \n rather than \r - and works) Any ideas (other than > say, passing the output through sed or something similar)? Could be that your problem is IO buffering on the sender side (i.e. the program you invoke). Alternatively, if you do not close stdin of the subprogram that might be waiting for some input. Cheers robert -- remember.guy do |as, often| as.you_can - without end