简体   繁体   English

读取“watch”命令 output 时,readline 在 paramiko.Channel 上挂起

[英]readline hangs on paramiko.Channel when reading “watch” command output

I am testing this code to read the output of watch command.我正在测试此代码以读取watch命令的 output。 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:我怀疑这与watch的工作方式有关,但我不知道出了什么问题或如何解决它:

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)有几个类似的问题,其中一些很老( 12 ,可能还有其他问题)

This does not happen with other commands that don't use watch either.其他不使用watch的命令也不会发生这种情况。

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) (在 Python 3.4.2 和 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.编辑 1 :我按照相关问题的答案中的建议合并了channel.set_combine_stderr(True) ,但仍然没有成功。 However, watch does produce a lot of output, so perhaps the problem is exactly that.但是, watch确实产生了很多 output,所以问题可能正是如此。 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.所以,可能这个问题几乎是Paramiko ssh die/hang with big output的重复,但让我想知道是否真的没有办法使用.readline() (在这种情况下通过__next__调用)并且必须求助于阅读固定缓冲区大小并手动组装行。

This probably hangs because watch does not produce newlines.这可能会挂起,因为watch不会产生换行符。 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.因此,这是一个非常特殊的情况,与其他问题和 SO 问题中报告的其他挂起无关。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM