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:

<CODE>
#!/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
</CODE>

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

-Jeremy

···

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:

<CODE>
#!/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
</CODE>

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...

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 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:

<CODE>
#!/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
</CODE>

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

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

···

On Thu, Oct 7, 2010 at 9:21 PM, Jeremy Bopp <jeremy@bopp.net> 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:

<CODE>
#!/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
</CODE>

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.

--
remember.guy do |as, often| as.you_can - without end
http://blog.rubybestpractices.com/

W dniu 07.10.2010 21:21, Jeremy Bopp pisze:

···

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:

<CODE>
#!/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
</CODE>

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.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

Both your answers works. THX!