From: Robert Klemme Date: 2009-03-20T23:57:14+09:00 Subject: Re: Wrapping applications in Ruby Few more remarks: 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 This will read the whole stream to the end! Which means, it will return only after the process died. > end > > 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 % If you have "\r" as line terminator, you can do the reading like this io.each "\r" do |line| # do whatever with line end e.g. robert@fussel ~ $ ruby -e '3.times {|i| printf "%03d\r", i}' | ruby -e '$stdin.each("\r") {|l| p l}' "000\r" "001\r" "002\r" robert@fussel ~ $ > $ cat wrapper.rb > input = "input.avi" > output = "output.mp4" > IO.popen("/usr/local/bin/HandBrakeCLI -i \"#{input}\" -o \"#{output}\"") > { |stdout| > p stdout.read See above. > } > > This prints nothing! Am I right in thinking that the popen block gets > called every time a \n character is captured by the pipe? (Your > 'counting.rb' uses \n rather than \r - and works) Any ideas (other than > say, passing the output through sed or something similar)? > > Thanks again, JP Note that the proper line reading (as suggested above) still does not help if the other program internally buffers IO. Kind regards robert -- remember.guy do |as, often| as.you_can - without end