From: Robert Klemme Date: 2010-10-08T18:32:17+09:00 Subject: Re: popen hangs out for user input On Thu, Oct 7, 2010 at 9:21 PM, Jeremy Bopp wrote: > On 10/7/2010 2:07 PM, Jeremy Bopp wrote: >> On 10/7/2010 1:40 PM, felix.leg wrote: >>> Hi, >>> >>> I want to use Ruby with latex,so I wrote a simple program which waits >>> for "\typein" command called from pdflatex: >>> >>> >>> #!/usr/bin/ruby >>> >>> file = IO.popen('pdflatex -interaction scrollmode test.tex','r+') #1 >>> >>> until file.readline.include? 'typein'; end >>> file.write "a line from RUBY" >>> file.readlines #2 >>> file.close >>> >>> >>> If I run the command from #1 in a sheel it works right: scrolls >>> "standard" latex asks, and stops for my "\@typein=". After I answer it >>> continues normally. >>> >>> But when I want do the same in Ruby with above code, it hangs out >>> waiting for input. It looks like #2 causes this, but I don't know why... >> >> It's probably because the write buffer for the pipe is not being >> flushed.  My preferred option to fix this sort of thing is to make the >> file object synchronous: >> >> file = IO.popen(.....) >> file.sync = true >> >> However, you might prefer to explicitly flush things instead: >> >> file.write(.....) >> file.flush >> ... >> file.write(.....) >> file.write(.....) >> file.flush > > One more thing: you may need to insert a newline at the end of the > strings you write or use #puts instead of #write.  Most interactive > programs like this expect a newline character to flag the end of data > entry for a field. Another reasonable thing to do is to close the write end of the pipe if you are done. Note also that expect helps working with interactive programs. And, of course, use the block form of IO.popen. require 'expect' IO.popen('pdflatex -interaction scrollmode test.tex','r+') do |file| file.expect /typein/, 10 do file.puts "a line from RUBY" end file.close_write file.each {} # read until EOF so process can do what it needs to end Btw, in 1.9 you can pass the command line as an array, i.e. IO.popen(%w{pdflatex -interaction scrollmode test.tex},'r+') do |file| file_name = "test.tex" # possibly read from ARGV IO.popen(%w{pdflatex -interaction scrollmode} << file_name, 'r+') do |file| Kind regards robert -- remember.guy do |as, often| as.you_can - without end http://blog.rubybestpractices.com/