Paramiko `exec_command`超时只对短超时有效,异常​​类型不匹配

Paramiko `exec_command` timeout only works for short timeout, and exception type doesn't match

我的 Python 脚本使用 Paramiko 库的 exec_command 函数在 ssh 上运行远程命令。为了测试此命令的 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.

所以我有两个问题:

感谢任何帮助!

SSHClient.exec_commandtimeout 参数有两个目的:

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

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

    如果你设置更长的超时时间(1s),通道打开成功。

    这确实抛出 SSHException ("Timeout opening channel.").

  • 阻塞操作的时间限制,如reading/writing。你没有做任何事情 reading/writing。这会抛出 socket.timeout.

    Channel.recv_exit_status好像没有用timeout。它永远等待。