Paramiko Recv()/read()/readline(s)() On Stderr Returns Empty String
Solution 1:
long story short: I've run into most of these problems and came up with my ultimate solution to most of my ssh related problems. Therefore feel free to have a look at this implementation of exec_command
avoiding most of the empty_response/stalling scenarios.
long story
The main problem here is that you exec_command()
is non-blocking and spawns a thread that takes care of the channels communication. This thread is waiting for incoming data and puts it into the channels buffers while the main thread may go on. This is where your problem lies. You're reading your buffers too early, even before you checked that your side received the exit_status
. Receiving the exit_status
confirms that the remote process exited with the given status code. Receiving the remote status code is not an indication that you've received all the data that may still be in transit. It may even arrive out-of-order at your side, saying that the status_code
may arrive even before all the data (stderr
,stdout
) was received.
While data is arriving, the main thread continues. In your case, the main thread tries to read from stdout
and stderr
once and then blocks until the exit_status
is ready. Note that the channel thread may still receive data from your remote command invocation. Also note that you'll have to manually empty buffers once your side received the remote exit_status
.
In your specific case this is what happens:
execute_command
spawns a new thread (lets call id exec_thread, managing the remote command invocation- while data may be received by the recently spawned thread, the main thread goes on.
- [main-thread] you're storing the current contents of the
stdout
,stderr
buffers inself.stdout
,self.stderr
. Note that you do not know if you've received all of the data ofstderr
orstdout
. Most likely you've just received a few chunks. - [exec_thread] happily receives data for
stdout
,stderr
while [main-thread] goes on. - [main-thread] busy-blocks until the
exit_status
is received. Again note, that at this point your buffers may still be full with recently receivedstderr
,stdout
chunks. - [main-thread] the
exit_status
is stored inself.exit_code
. [exec_thread] is still alive, may still receive some out of order data. input buffers might still be filled. - [main-thread] returns from
run_cmd
Note that [exec_thread] for that channel - paramiko creates one thread per channel invocation (i.e. exec_command
) - is still alive and they'll sum up idling around and creating problems until you manually close them (stdout.channel.close()
).
Post a Comment for "Paramiko Recv()/read()/readline(s)() On Stderr Returns Empty String"