Trying to implement a test server in paramiko
without having to modify the client for testing,
I have stumbled across the problem how to close the stdout
stream, making `stdout.read()ยด not hang forever without going too low-level on the client's side. So far I have been able to communicate the completed command (simple text output to stdout) execution by:
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
but I have not found a method to avoid the middle two lines in
_,stdout,_ = ssh.exec_command("<FILEPATH>")
stdout.channel.recv_exit_status()
stdout.channel.close()
print(stdout.read())
which is already a good workaround not having to call channel.exec_command
diretly (found here).
Not closing the stdout
stream, my output will not print and the underlying transport on the server also remains active forever.
Closing the channel with stdout.channel.close()
does not really have an effect and alternatively using os.close(writemessage.fileno())
(Difference explained here) does not work because the paramiko.channel.ChannelFile
object used for the I/O streams "has no attribute 'fileno'". (Detailed explanation found here.)
Also, closing the channel directly on the server side throws a SSHException
for the client..
Solutions proposed here do always modify the client side but I know from using my client script on the actual server that it must be possible without these additional lines!