Question

I have a Ruby script that spawns a process and uses expect to wait for a request for input, provide that input and then when the process is finished, to spawn a new process.

Initially the problem was that the script didn't wait for the first process to finish, and executed the next line in the script.

So I added Process.wait(pid) to the script, but now the script hangs waiting for input on the second PTY.spawn at Process.wait(pid).

I'm running the script with Ruby 1.9.2, as I know there were some problems with PTY.spawn in Ruby 1.8.7.

The script looks like:

#!/usr/bin/env ruby
require 'pty'
require 'expect'


  PTY.spawn(" apt-get install policycoreutils ") do |reader, writer, pid|
    puts reader.expect(/Do you want to continue/)
    writer.printf("Y\n")
    Process.wait(pid)
  end

  PTY.spawn(" apt-get install libmagick9-dev ") do |reader, writer, pid|
    puts reader.expect(/Do you want to continue/)
    writer.printf("Y\n")
    Process.wait(pid)
  end

Does anyone know why the script hangs at Process.wait(pid) for the second PTY.spawn?

Was it helpful?

Solution

To help you debug, I reduced the code a bit, and spawned a more benign command:

require 'pty'
require 'expect'

PTY.spawn("sleep 1;echo 1") do |reader, writer, pid|
  puts reader.expect(/1/)
  Process.wait(pid)
end

PTY.spawn("sleep 1;echo 2") do |reader, writer, pid|
  puts reader.expect(/2/)
  Process.wait(pid)
end

This outputs:

ruby test.rb 
1
2

This implies to me that the problem lies in the apt-get commands.

OTHER TIPS

Actually I found a solution and it was very simple but a little surprising. What the second apt-get really asks is

 "Do you want to continue [Y/n]? "

I think what was happening was that the expect was matching on the first part of this string and sending the "Y" before the string had finished being fully output and the apt-get wasn't ready to receive the "Y". Once I changed the expect match to the string above, as in the code below, then it all worked fine.

PTY.spawn(" apt-get install libmagick9-dev ") do |reader, writer, pid|
   puts reader.expect(/Do you want to continue \[Y\/n\]\? /)
   writer.printf("Y\n")
   Process.wait(pid)
 end
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top