3

I am testing this code to read the output of watch command. I suspect it has to do with how watch works, but I can't figure out what's wrong or how to work around it:

import paramiko

host = "micro"
# timeout = 2  # Succeeds
timeout = 3  # Hangs!
command = 'ls / && watch -n2 \'touch "f$(date).txt"\''

ssh_client = paramiko.SSHClient()
ssh_client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh_client.connect(host, password='', look_for_keys=False)

transport = ssh_client.get_transport()
channel = transport.open_session()
channel.get_pty()
channel.settimeout(timeout)
channel.set_combine_stderr(True)
stdout = channel.makefile()
channel.exec_command(command)

for line in stdout:  # Hangs here
    print(line.strip())

There are several similar issues, some of them quite old (1, 2, and probably others)

This does not happen with other commands that don't use watch either.

Does someone know what's special about this particular command and / or how to reliably set a timeout for the read operation?

(Tested on Python 3.4.2 and paramiko 1.15.1)

Edit 1: I incorporated channel.set_combine_stderr(True) as suggested in this answer to a related question, but still didn't do the trick. However, watch does produce a lot of output, so perhaps the problem is exactly that. In fact, using this command removed the hanging:

command = 'ls / && watch -n2 \'touch "f$(date).txt"\' > /dev/null'

So, probably this question is almost a duplicate of Paramiko ssh die/hang with big output, but makes me wonder if there's really no way to use .readline() (called through __next__ in this case) and one has to resort to read with a fixed buffer size and assemble the lines manually.

Martin Prikryl
  • 188,800
  • 56
  • 490
  • 992
astrojuanlu
  • 6,744
  • 8
  • 45
  • 105

1 Answers1

0

This probably hangs because watch does not produce newlines. If one replaces

for line in stdout:
    print(line.strip())

with a busy loop with

stdout.readline(some_fixed_size)

it can be seen that the bytes never contain a newline character. Therefore, this is a very special case and is not related to other hangs reported in other issues and SO questions.

astrojuanlu
  • 6,744
  • 8
  • 45
  • 105