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

问题描述 投票:0回答:1

我的 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
参数值),异常类型是
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

如有任何帮助,我们将不胜感激!

python ssh paramiko
1个回答
2
投票

timeout
SSHClient.exec_command
参数有两个目的:

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

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

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

    这确实会抛出

    SSHException
    “超时打开通道。”)。

  • 阻塞操作的时间限制,例如读/写。您没有进行任何读/写。这会抛出

    socket.timeout

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

© www.soinside.com 2019 - 2024. All rights reserved.