user1018517
user1018517

Reputation:

Python Paramiko exec_command timeout doesn't work?

I got the following ssh command,

    try:
        print 'trying to restart'
        self.ssh.exec_command(RR_CMD % (self.path_ext, self.rport), timeout=1)
        print 'restarted'
    except:
        self.ssh.close()
        self.ssh = ssh.create_ssh_client(self.ip, self.port, self. username, self.password)
        self.restart()

Basically I'm trying to restart a remote perl script. But sometimes, like let's say 1 out of 2000 - my python program is freezing over the exec_command line for sometimes up to a few minutes!

I would like to use the timeout function, which I set to 1 second, but it doesn't work for some reason.

Upvotes: 5

Views: 3897

Answers (3)

For those who use recv_exit_status:

import paramiko

ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.connect('192.168.10.1', username='root', password='password')
_, out, err = ssh.exec_command("python3 -c 'from time import sleep\nsleep(5)'")

# this
# print(out.channel.recv_exit_status())
# change this to
out.channel.status_event.wait(timeout=10)  # < 5 raise assert
assert out.channel.status_event.is_set()
print(out.channel.exit_status)
ssh.close()
print("end script")

Upvotes: 0

Wyrmwood
Wyrmwood

Reputation: 3609

I've had issues with the timeout in exec_command not being honored how I would anticipate. For example, I had the timeout set to 60 and found a hung command running all night. What I was doing before was

response = client.exec_command(command, timeout=60)
returncode = response[0].channel.recv_exit_status()

But with a timeout of None or any value, it was hanging on recv_exit_status, Now, instead, I am just managing the timeout myself, since exec_command is non-blocking, by polling channel.exit_status_ready.

start = time.time()
while time.time() < start + timeout:
    if response[0].channel.exit_status_ready():
        break
    time.sleep(1)
else:
    raise TimeoutError(f'{command} timed out on {hostname}')
returncode = response[0].channel.recv_exit_status()

Upvotes: 6

tanglong
tanglong

Reputation: 278

What about your version of paramiko?

The latest version of paramiko supported argument timeout.

Paramiko Changelog v1.10.0:

Add timeout parameter to SSHClient.exec_command for easier setting of the command’s internal channel object’s timeout. Thanks to Cernov Vladimir for the patch.

Upvotes: 0

Related Questions