我的 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
?如有任何帮助,我们将不胜感激!
timeout
的
SSHClient.exec_command
参数有两个目的:
打开 SSH“exec”通道的时间限制。
这可能会触发 0.5 秒的超时,因为在服务器上打开通道需要更长的时间。 IE。超时与您的无限命令无关。
如果设置较长的超时时间(1s),则通道打开成功。
这确实会抛出
SSHException
(“超时打开通道。”)。
阻塞操作的时间限制,例如读/写。您没有进行任何读/写。这会抛出
socket.timeout
。
Channel.recv_exit_status
似乎没有使用timeout
。它永远等待。