My Python script runs a remote command over ssh, using the Paramiko library's exec_command function. To test the timeout option to this command, I'm sending a do-nothing loop, and verifying that the exec_command function times out. However, the timeout only fires when I set it to a value less than 1. For example, the following code times out as expected:
command = 'while true; do :; done'
ssh = paramiko.SSHClient()
ssh.connect(ip, port=port, username=user, pkey=key, timeout=10)
_, stdout, stderr = ssh.exec_command(command, timeout=0.5)
print("Running command: {}".format(command))
exit_code = stdout.channel.recv_exit_status()
But when I change the timeout argument value to 1, it does not time out.
Another odd thing is that when the timeout does occur (with the 0.5 arg value), the exception type is paramiko.ssh_exception.SSHException, rather than socket.timeout, as the docs say it should be. The full exception message is paramiko.ssh_exception.SSHException: Timeout openning channel. But the stack trace starts at the exec_command line above, not the connect line:
Running command: while true; do :; done
Traceback (most recent call last):
File "./t.py", line 40, in <module>
_, stdout, stderr = ssh.exec_command(command, timeout=0.5)
File "/usr/lib/python3/dist-packages/paramiko/client.py", line 414, in exec_command
chan = self._transport.open_session(timeout=timeout)
File "/usr/lib/python3/dist-packages/paramiko/transport.py", line 703, in open_session
timeout=timeout)
File "/usr/lib/python3/dist-packages/paramiko/transport.py", line 828, in open_channel
raise SSHException('Timeout openning channel.')
paramiko.ssh_exception.SSHException: Timeout openning channel.
So I have two questions:
- Why does a timeout of
0.5work, but1or greater does not? - Why does the exception report a timeout opening the channel, instead of a
socket.timeout, even though the exception is coming fromexec_command, notconnect?
Any help is appreciated!