Skip to content

Instantly share code, notes, and snippets.

@kdheepak
Created January 2, 2019 21:01
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save kdheepak/c18f030494fea16ffd92d95c93a6d40d to your computer and use it in GitHub Desktop.
Save kdheepak/c18f030494fea16ffd92d95c93a6d40d to your computer and use it in GitHub Desktop.
paramiko non blocking example
import sys
import paramiko
import os
import select
import getpass
import time
rpi = {
"username": getpass.getuser(),
"hostname": "hostname.of.server.here"
}
command = "cd /path/to/folder/ && python test_worker.py"
ssh = paramiko.SSHClient()
ssh.load_system_host_keys()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.connect(**rpi)
ssh_stdin, ssh_stdout, ssh_stderr = ssh.exec_command(command)
def worker(stdout, stderr):
# Wait for the command to terminate
print("Status of worker is {}".format(stdout.channel.exit_status_ready()))
while not stdout.channel.exit_status_ready():
time.sleep(1)
print("Status of worker is {}".format(stdout.channel.exit_status_ready()))
if stdout.channel.recv_ready():
# Only print data if there is data to read in the channel
print("Worker stdout.channel.recv_ready: {}".format(stdout.channel.recv_ready()))
rl, wl, xl = select.select([stdout.channel], [], [], 0.0)
if len(rl) > 0:
# Print data from stdout
print("Output: {}".format(stdout.channel.recv(1024).decode("utf-8")))
print("Reading output from master")
worker(ssh_stdout, ssh_stderr)
print("Finished reading output from master")
import time
import sys
i = 0
while True:
time.sleep(5)
i = i + 5
print("At time {}".format(i))
if i > 15:
sys.exit(0)
@kdheepak
Copy link
Author

kdheepak commented Jan 2, 2019

This is the output of running the code.

$ python paramiko_runner.py                                                                                                                                                                                                                    
Reading output from master
Worker function printer
Status of worker is False
Status of worker is False
Status of worker is False
Status of worker is False
Status of worker is False
Status of worker is False
Status of worker is False
Status of worker is False
Status of worker is False
Status of worker is False
Status of worker is False
Status of worker is False
Status of worker is False
Status of worker is False
Status of worker is False
Status of worker is False
Status of worker is False
Status of worker is False
Status of worker is False
Status of worker is False
Status of worker is False
Status of worker is False
Status of worker is True
Worker stdout.channel.recv_ready: True
Output: At time 5
At time 10
At time 15
At time 20

Finished reading output from master

I was expecting the "Output" to be printed in real time, instead of when the process ends.

@EugenKlexin
Copy link

Because "Python’s standard out is buffered.” , you have to flush the print output:
print("At time {}".format(i), flush = True)

@kdheepak
Copy link
Author

Thanks for the input! I will try that!

@rocojorge
Copy link

I have a question, if these code is non-blocking example, when you invoke a shell and use it with send() a recv() instead of exec_command and stdout, is the shell that I have generated a blocking socket or a non-blocking socket? I'm very lost right now.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment