有很多主题涉及标题的一部分,但没有任何东西可以完全满足整个事情.我在远程服务器上推送一个命令,经过很长的执行时间后需要完整的输出,比如5分钟左右.使用通道我能够设置超时,但是当我读回stdout时,我只得到了一小部分输出.解决方案似乎是等待channel.exit_status_ready().这对成功的呼叫起作用,但是失败的呼叫永远不会触发信道超时.在查看了文档之后,我推测这是因为超时仅适用于读取操作,并且等待退出状态不符合条件.这是尝试:
channel = ssh.get_transport().open_session()
channel.settimeout(timeout)
channel.exec_command(cmd) # return on this is not reliable
while True:
try:
if channel.exit_status_ready():
if channel.recv_ready(): # so use recv instead...
output = channel.recv(1048576)
break
if channel.recv_stderr_ready(): # then check error
error = channel.recv_stderr(1048576)
break
except socket.timeout:
print("SSH channel timeout exceeded.")
break
except Exception:
traceback.print_exc()
break
Run Code Online (Sandbox Code Playgroud)
漂亮,不是吗?希望它有效.
我第一次尝试解决方案是使用time.time()来启动,然后检查start - time.time()> timeout.这看起来很简单,但在我目前的版本中,我输出start-time.time(),其中一个固定的超时应该触发一个中断...并且看到差异使得超时加倍并且不会发生中断.为了节省空间,我会提到我的第三次尝试,我已经用这个尝试了.我在这里读到关于使用select.select等待输出的问题,并在文档中注意到那里也有超时.正如您将从下面的代码中看到的那样,我混合了所有三种方法 - 通道超时,time.time超时和选择超时 - 但仍然必须终止进程.这是frankencode:
channel = ssh.get_transport().open_session()
channel.settimeout(timeout)
channel.exec_command(cmd) # return on this is not reliable
print("{0}".format(cmd))
start = time.time()
while True:
try:
rlist, wlist, …Run Code Online (Sandbox Code Playgroud)