Popen hangs out for user input

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…

On 10/7/2010 1:40 PM, felix.leg wrote:

until file.readline.include? ‘typein’; end
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

-Jeremy

On 10/7/2010 2:07 PM, Jeremy B. wrote:

But when I want do the same in Ruby with above code, it hangs out

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.

-Jeremy

On Thu, Oct 7, 2010 at 9:21 PM, Jeremy B. [email protected] wrote:

file = IO.popen(‘pdflatex -interaction scrollmode test.tex’,‘r+’) #1

However, you might prefer to explicitly flush things instead:
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

W dniu 07.10.2010 21:21, Jeremy B. pisze:

file = IO.popen(‘pdflatex -interaction scrollmode test.tex’,‘r+’) #1

However, you might prefer to explicitly flush things instead:
programs like this expect a newline character to flag the end of data
entry for a field.

-Jeremy

Both your answers works. THX!