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.
所以我有两个问题:
- 为什么
0.5
的超时有效,但 1
或更大的超时无效?
- 为什么异常报告打开通道超时,而不是
socket.timeout
,即使异常来自 exec_command
,而不是 connect
?
感谢任何帮助!
SSHClient.exec_command
的 timeout
参数有两个目的:
打开 SSH "exec" 通道的时间限制。
这里可能会触发0.5秒的超时,因为在你的服务器上打开频道需要更长的时间。 IE。超时与您的无限命令无关。
如果你设置更长的超时时间(1s),通道打开成功。
这确实抛出 SSHException
("Timeout opening channel.").
阻塞操作的时间限制,如reading/writing。你没有做任何事情 reading/writing。这会抛出 socket.timeout
.
Channel.recv_exit_status
好像没有用timeout
。它永远等待。
我的 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.
所以我有两个问题:
- 为什么
0.5
的超时有效,但1
或更大的超时无效? - 为什么异常报告打开通道超时,而不是
socket.timeout
,即使异常来自exec_command
,而不是connect
?
感谢任何帮助!
SSHClient.exec_command
的 timeout
参数有两个目的:
打开 SSH "exec" 通道的时间限制。
这里可能会触发0.5秒的超时,因为在你的服务器上打开频道需要更长的时间。 IE。超时与您的无限命令无关。
如果你设置更长的超时时间(1s),通道打开成功。
这确实抛出
SSHException
("Timeout opening channel.").阻塞操作的时间限制,如reading/writing。你没有做任何事情 reading/writing。这会抛出
socket.timeout
.Channel.recv_exit_status
好像没有用timeout
。它永远等待。