Backport #1973
Updated by jeremyevans0 (Jeremy Evans) almost 5 years ago
=begin I am attempting to control several servers remotely using SSH and Ruby's expect module. Please see the following code: 128 print "Configuring #{host}..." 129 130 begin 131 reader, writer, pid = PTY.spawn("scp #{@configFile1} #{@configFile2} #{@user}@#{host}:") 132 reader.sync = true 133 writer.sync = true 134 135 reader.expect(/[pP]assword:|Are you sure/) do |rArray| 136 response = rArray[0] 137 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 myhost.mydomain.com..../deploy-dist-config.rb:131:in `run': pty - exited: 6879 (PTY::ChildExited) from ./geploy-dist-config.rb:127:in `each' 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. =end