Bug #1973

PTY module ignores exception handling block; renders Expect useless

Added by sfalvo (Samuel Falvo) over 9 years ago. Updated about 8 years ago.

Target version:
ruby -v:
ruby 1.8.6 (2008-08-11 patchlevel 287) [universal-darwin9.0]


I am attempting to control several servers remotely using SSH and Ruby's expect module. Please see the following code:

128 print "Configuring #{host}..."
130 begin
131 reader, writer, pid = PTY.spawn("scp #{@configFile1} #{@configFile2} #{@user}@#{host}:")
132 reader.sync = true
133 writer.sync = true
135 reader.expect(/[pP]assword:|Are you sure/) do |rArray|
136 response = rArray[0]
138 if response =~ /Are you sure/
139 writer.puts "yes"
140 elsif response =~ /[pP]assword:/
141 writer.puts @password
142 else
143 puts "WARNING: unrecognized response: #{response}"
144 end
145 end
146 rescue PTY::ChildExited
147 puts "Swallowing PTY::ChildExited"
148 ensure
149 sleep(3) # Give it 3 seconds to complete.
150 Process.kill('KILL', pid)
151 end

Attempting to execute this code results in an exception report:

Configuring run': pty - exited: 6879 (PTY::ChildExited)
from ./geploy-dist-config.rb:127:in
from ./geploy-dist-config.rb:127:in `run'
from ./geploy-dist-config.rb:200

Notice that it's resulting in an exception EVEN THOUGH I have wrapped the code in a begin/rescue/ensure/end block!! I might as well not even have the begin/end block at all.

Trying to use Process#waitpid results in an eternal hang of my session. Thus, the ONLY way recycle PTYs is to explicitly kill the process that PTY.spawn launched. :-(

This is a deal-breaker for me; if I cannot find a work-around to this, I'm afraid I have to rewrite my software in another language and slip my schedule. I really pray I don't have to do that. I know an emergency on my part doesn't constitute an emergency on your part, but if I can be contacted about this as soon as possible, I would be much obliged. This is blocking a corporate demo.

Thank you for your time and considerations.

Also available in: Atom PDF