Paramiko 服务器:向客户端发出 stdout 已关闭的信号
Paramiko Server: Signalling the client that stdout is closed
尝试在 paramiko
中实现测试服务器,而无需修改客户端进行测试 ,
我偶然发现了如何关闭 stdout
流的问题,使“stdout.read()”不会永远挂起而不会在客户端太低级别。到目前为止,我已经能够通过以下方式传达完成的命令(简单文本输出到标准输出)执行:
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) does not work because the paramiko.channel.ChannelFile
object used for the I/O streams "has no attribute 'fileno'". (Detailed explanation found 。)
此外,直接在服务器端关闭通道会为客户端抛出 SSHException
..
建议的解决方案 here 总是修改客户端,但我从在实际服务器上使用我的客户端脚本知道,没有这些额外的行一定是可能的!
在 check_channel_exec_request
中,发送退出状态后关闭服务器端的通道,根据协议规范,该规范声明通道在命令执行的整个生命周期内处于活动状态,并在之后关闭。
这导致 channel.eof()
在客户端成为 True
,表示命令已完成并且从通道读取不再挂起。
def check_channel_exec_request(self,channel,command):
writemessage = channel.makefile("w")
writemessage.write("SOME COMMAND SUBMITTED")
writemessage.channel.send_exit_status(0)
channel.close()
return True
看到这个 embedded server for integration testing based on paramiko that has been around for some years for reference - it implements exec requests among others. Speaking from experience, I would recommend instead using an embedded OpenSSH based server, an example of which can also be found on the same repository。 Paramiko 代码并不是特别没有错误。
我遇到过一个与此类似的问题。我们的问题是我们一退出就关闭了整个 session。显然我们的客户(libssh2)不喜欢那样。因此,我们每次关闭一个频道时都会继续尝试接受一个新频道,直到 transport.is_active()
为 False
。
尝试在 paramiko
中实现测试服务器,而无需修改客户端进行测试 ,
我偶然发现了如何关闭 stdout
流的问题,使“stdout.read()”不会永远挂起而不会在客户端太低级别。到目前为止,我已经能够通过以下方式传达完成的命令(简单文本输出到标准输出)执行:
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) does not work because the paramiko.channel.ChannelFile
object used for the I/O streams "has no attribute 'fileno'". (Detailed explanation found
此外,直接在服务器端关闭通道会为客户端抛出 SSHException
..
建议的解决方案 here 总是修改客户端,但我从在实际服务器上使用我的客户端脚本知道,没有这些额外的行一定是可能的!
在 check_channel_exec_request
中,发送退出状态后关闭服务器端的通道,根据协议规范,该规范声明通道在命令执行的整个生命周期内处于活动状态,并在之后关闭。
这导致 channel.eof()
在客户端成为 True
,表示命令已完成并且从通道读取不再挂起。
def check_channel_exec_request(self,channel,command):
writemessage = channel.makefile("w")
writemessage.write("SOME COMMAND SUBMITTED")
writemessage.channel.send_exit_status(0)
channel.close()
return True
看到这个 embedded server for integration testing based on paramiko that has been around for some years for reference - it implements exec requests among others. Speaking from experience, I would recommend instead using an embedded OpenSSH based server, an example of which can also be found on the same repository。 Paramiko 代码并不是特别没有错误。
我遇到过一个与此类似的问题。我们的问题是我们一退出就关闭了整个 session。显然我们的客户(libssh2)不喜欢那样。因此,我们每次关闭一个频道时都会继续尝试接受一个新频道,直到 transport.is_active()
为 False
。