0

I want to run an auto deployment of some software on a remote server. Anyway, the output of the remote command always blocks and never ends. I have checked the remote server and I can confirm that the command is still running, though the stdout printed by paramiko blocks.

I have read the solution from this post: LINK

import paramiko
import select

client = paramiko.SSHClient()
client.load_system_host_keys()
client.connect('host.example.com')
channel = client.get_transport().open_session()
channel.exec_command("packstack --allinone")
while True:
    if channel.exit_status_ready():
        break
    rl, wl, xl = select.select([channel], [], [], 0.0)
    if len(rl) > 0:
        print channel.recv(1024)

Each time when I use Ctrl + C to force the script stop, it seems to be stuck at rl, wl, xl = select.select([channel], [], [], 0.0).

For reference, I also read this post .But no luck found.

How can I modify the code to make it work with the long-lasting and large-outputting command?

Now I found the problem. Actually it was not stuck at rl, wl, xl = select.select([channel], [], [], 0.0). Since the timeout was set to 0.0, it was in a non-blocking pattern.

Therefore, the problem is that, the program executed the while loop forever but it just could not receive anything from the channel, although the remote process was still outputting stuff.

I assume this could be caused by either paramiko or a bad remote server.

Now my solution is to rerun my command when the channel could not receive anything in a limited time, say 120 seconds, while exit signal not received.

Community
  • 1
  • 1
Marine Lu
  • 31
  • 6

1 Answers1

0

It use to happen when there is no data in stdout or there is a line without eol (i.e. in a read statement inside a sh script). Try setting 'get_pty=True', then reading only the bytes in stdout. Here is an example using exec_command directly with the SSHClient.

ssh = paramiko.SSHClient()
...
stdin, stdout, stderr = ssh.exec_command("your-command",get_pty=True)
stdout.flush()
nbytes = 0
while (len(stdout.channel.in_buffer)==0):
     continue

nbytes=len(stdout.channel.in_buffer)
print(nbytes)
stdout.read(nbytes)
nachopol
  • 43
  • 5