我正在尝试向/从简单的WebSockets UI流式传输bash shell,但是我无法重定向IO。我想启动一个bash实例,并将stdout和stdin连接到与我的Web UI交互的write_message()和on_message()函数。这是我正在尝试做的简化版本:
class Handler(WebSocketHandler):
def open(self):
print "New connection opened."
self.app = subprocess.Popen(["/bin/bash", "--norc", "-i"], stdout=subprocess.PIPE, stdin=subprocess.PIPE, shell=False)
thread.start_new_thread(self.io_loop, ())
def on_message(self, message):
self.app.stdin.write(message)
def on_close(self):
self.app.terminate()
def io_loop(self):
while self.app.poll() is None:
line = self.app.stdout.readline()
if line:
self.write_message(line)
虽然bash似乎开始并且on_message确实被调用,但我没有得到任何输出。 readline()仍然阻塞。我已经尝试过stdout.read(),stdout.read(1)和各种缓冲区修改,但仍然没有输出。我还尝试在on_message中使用尾随'\ n'的硬编码命令来隔离问题,但我仍然没有从readline()获得任何输出。
理想情况下,我希望实时流式传输写入stdout的每个字节,而无需等待EOL或任何其他字符,但我很难找到合适的API。任何指针都会受到赞赏。
答案 0 :(得分:3)
在我看来,就像这一行:
line = self.app.stdout.readline()
将阻止ioloop运行,因为应用程序将花费大部分时间挂在readline()
等待应用程序写入一些输出。为了实现这一点,您必须获得流程的stdin
和stdout
(以及stderr
的内容? - 您需要捕获它),将它们切换为非阻塞模式,并将它们添加到ioloop
花费时间循环的文件描述符集。