Paramiko`exec_command`超时仅适用于短超时,并且异常类型不匹配

时间:2019-05-10 13:53:08

标签: python ssh paramiko

我的Python脚本使用Paramiko库的ssh函数在exec_command上运行远程命令。为了测试此命令的timeout选项,我发送了一个空循环,并验证exec_command函数是否超时。但是,仅当我将其设置为小于1的值时才会触发超时。例如,以下代码按预期超时:

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()

但是当我将timeout参数值更改为1时,它不会超时。

另一个奇怪的事情是,当确实发生超时(使用0.5 arg值)时,异常类型为paramiko.ssh_exception.SSHException,而不是文档所说的socket.timeout。 。完整的异常消息为paramiko.ssh_exception.SSHException: Timeout openning channel.,但是堆栈跟踪从以上exec_command行开始,而不是connect行:

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.

所以我有两个问题:

  • 为什么0.5超时无效,而1或更高的超时无效?
  • 即使异常来自socket.timeout而不是exec_command,为什么异常会报告超时而不是connect打开通道?

感谢您的帮助!

1 个答案:

答案 0 :(得分:1)

SSHClient.exec_commandtimeout参数有两个目的:

  • 打开SSH“ exec”通道的时间限制。

    这可能会触发0.5秒的超时,因为打开服务器上的通道需要更长的时间。即超时与您的无限命令无关。

    如果您设置更长的超时时间(1s),则该频道将成功打开。

    这确实引发了SSHException“超时打开频道”。)。

  • 阻止操作的时间限制,例如读/写。您没有做任何读/写操作。这样会抛出socket.timeout

    Channel.recv_exit_status似乎没有使用timeout。它永远等待着。