in reply to Any way to make it quicker?

Two pure-guesses:

  1. Do you need to instantiate a new SSH2 object every time?   Can you re-use a single one?   Could resources be consumed, and not freed, say within the underlying library, when you create one object after another?   It is well worth exploring that possibility.
  2. “Always be tidy.”   If you connect() successfully, then explicitly disconnect().   You are telling each host, as well as the library on your side, “Say goodnight, Gracie.”   Expressly telling it to bring that connection to an orderly conclusion, and presumably to clean-up any internal resources associated with it.

Also, I have sometimes found it to be “strangely useful” to add explicit pauses into such programs.   “Tell it to wait a second.”   After all, you are doing something that involves a remote computer system and a communications line, so there is something to be said maybe for giving it just a little extra time to take a deep breath.   Those “once in a blue moon” problems that cause your pager to go-off at 2:30 AM just might be avoided that way.

It’s a good guess that this script is somehow stalling, and one common cause of stalls is simply that some resource or another runs-out.   Because there is a lot of asynchronous activity going on here, the effects might not be very consistent or reproducible.  

I would also suggest that you add explicit calls to the error() method, perhaps in a list context so that you get everything it has to offer.   Don’t assume that everything worked, and also don’t assume that, if something did seem to work, there might not also be a useful message to be found.   Sometimes there are “warning” or “informational” messages to be had from a library that are extremely important, but you have to go digging for them.   Look for these messages at several strategic places and at least print them to STDERR.