Paramiko Server:告知客户端stdout已关闭

时间:2017-12-03 22:00:09

标签: python python-3.x server stdout paramiko

尝试在paramiko 中实施测试服务器,而无需修改客户端进行测试, 我偶然发现了如何关闭stdout流的问题,使`stdout.read()'不会永远挂起,而不会在客户端过低。到目前为止,我已经能够通过以下方式将完成的命令(简单文本输出到stdout)执行:

class FakeCluster(paramiko.server.ServerInterface):
    def check_channel_exec_request(self,channel,command):
        writemessage = channel.makefile("w")
        writemessage.write("SOME COMMAND SUBMITTED")
        writemessage.channel.send_exit_status(0)
        return True

但我还没有找到避免

中间两行的方法
_,stdout,_ = ssh.exec_command("<FILEPATH>")
    stdout.channel.recv_exit_status()
    stdout.channel.close()
    print(stdout.read())

这已经是一个很好的解决方法,无需直接调用channel.exec_command(找到here)。 不关闭stdout流,我的输出将不会打印,服务器上的底层传输也将永远保持活动状态。

使用stdout.channel.close()关闭频道实际上没有效果,或者使用os.close(writemessage.fileno())(差异解释here)不起作用,因为用于I的paramiko.channel.ChannelFile对象/ O streams“没有属性'fileno'”。 (详细解释见here。)

此外,直接在服务器端关闭频道会为客户端抛出SSHException ..

建议的解决方案here总是修改客户端,但我知道在实际服务器上使用我的客户端脚本,如果没有这些额外的行,它必须是可能的!

2 个答案:

答案 0 :(得分:0)

isSelected中,根据协议规范,在发送退出状态后关闭服务器端的通道,该协议规范指出在执行命令的每个生命周期内通道处于活动状态并在之后关闭。

这导致check_channel_exec_request在客户端为channel.eof(),表示命令已完成,并且从频道读取不再挂起。

True

根据已经存在多年的paramiko参考此embedded server for integration testing以供参考 - 它实现了exec请求等。根据经验,我建议使用基于OpenSSH的嵌入式服务器example of which can also be found on the same repository。 Paramiko代码并不是特别没有错误。

答案 1 :(得分:0)

我遇到了一个与此类似的问题。我们的问题是,退出会议后,我们将结束整个会议。显然,我们的客户端(libssh2)不喜欢这样。因此,我们每次关闭频道都会一直尝试接受一个新频道,直到const fn = (a: {[k: string]: any}, b: string, c: string) => { return a[b]?.[c]?.d } transport.is_active()