user3388884
user3388884

Reputation: 5068

get_pty() via sshClient sometimes hangs forever with paramiko

In an automation script, i need to ssh into several servers to gather some data. Unfortunately, few of them seems to have intermittent issues where the connection hangs forever on get_pty().

Here's a snippet of my code. Is there something I can do to kill the connection? I'm using python of course, and unfortunately with python, there is no easy way to kill a thread either :(

client = paramiko.SSHClient()
client.load_system_host_keys()
client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
connect(hostname, port=port, username=username, password=password, timeout=30)
self.__chan = self.__client.get_transport().open_session()
print self.__chan
print ' after'
print self.__chan.get_pty()

output

<paramiko.Channel 1 (open) window=0 -> <paramiko.Transport at 0xd49410L (cipher aes128-ctr, 128 bits) (active; 1 open channel(s))>>
 after

I believe the issue has to do with a failed attempt to get_transport() or open_session() properly. If so, how can i detect if an issue occurred?

Upvotes: 0

Views: 14609

Answers (1)

Nick
Nick

Reputation: 324

Per the documentation for paramiko regarding get_pty, "It isn’t necessary (or desirable) to call this method if you’re going to exectue a single command with exec_command." http://docs.paramiko.org/en/1.13/api/channel.html#paramiko.channel.Channel.get_pty

Do you have a specific reason for invoking the pseudo-terminal? If you use paramiko.client.SSHClient.exec_command you do not need to invoke one. Depending on your version of paramiko, exec_command also accepts a timeout parameter so that the command will only block for a certain amount of time. Should your version not allow this parameter, you can subclass the client to add it.

from paramiko import SSHClient

class SSHClient_with_Timeout(SSHClient): 
    ## overload the exec_command method 
    def exec_command(self, command, bufsize=-1, timeout=None): 
        chan = self._transport.open_session() 
        chan.settimeout(timeout) 
        chan.exec_command(command) 
        stdin = chan.makefile('wb', bufsize) 
        stdout = chan.makefile('rb', bufsize) 
        stderr = chan.makefile_stderr('rb', bufsize) 
        return stdin, stdout, stderr 

If that's not the solution you're looking for, you could also set up logging. paramiko logs to the logger "paramiko", so invoking logging.basicConfig(level=logging.DEBUG) will allow you to see what paramiko is up to right before the 'hang.'

Upvotes: 2

Related Questions