mohangk.org/blog

Thoughts, somewhat explained

Paramiko SSHClient.exec_command timeout workaround

| 0 comments

For some reason Paramiko’s SSHClient.exec_command has an issue with setting timeouts.

For example, despite passing the timeout=3 to the client.connect, the code below will not timeout if the connection to the server is flaky.

client = paramiko.SSHClient()
client._policy = paramiko.AutoAddPolicy()
client.load_system_host_keys()
client.connect(host, int(port), username=getpass.getuser(),
                       timeout=3)
stdin, stdout, stderr = client.exec_command('ls -l /tmp')
print stdout.read()

 

I found a nice workaround on a comment to a blog post by a chap who was having the same problem - http://www.stillhq.com/commentform.cgi?post=python/paramiko/000004 and I am blogging it here for posterity. It involves overiding the exec_command method to accept at timeout like so:

class mySSHClient(paramiko.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
client = mySSHClient()
client._policy = paramiko.AutoAddPolicy()
client.load_system_host_keys()
client.connect(host, int(port), username=getpass.getuser())
stdin, stdout, stderr = client.exec_command('ls -l /tmp',timeout=3)
print stdout.read()

Works like a charm!

Leave a Reply

Required fields are marked *.

*