2011-11-18 178 views
4

我试图从简单的WebSockets UI流入/从一个bash shell,但我在重定向IO时遇到问题。我想启动一个bash实例,并将stdout和stdin连接到与我的Web UI交互的write_message()和on_message()函数。这里是什么,我试图做一个简化版本:在Python中的流标准输出/标准输出

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) 

虽然庆典似乎开始和ON_MESSAGE不会被调用,我没有得到任何输出。 readline()仍然阻塞。我试过stdout.read(),stdout.read(1)和各种缓冲区修改,但仍然没有输出。我也尝试了在on_message中使用后缀'\ n'的硬编码命令来隔离问题,但是我仍然没有从readline()获得任何输出。

理想情况下,我希望将每个字节实时写入stdout,而不等待EOL或任何其他字符,但我很难找到正确的API。任何指针将不胜感激。

+0

冲洗流帮助吗? –

+0

不,我甚至尝试用sys.stdout.flush()替换一个简单的echo脚本。 – ca4221

+0

这是什么WebSocketHandler? –

回答

3

这在我看来像行:

line = self.app.stdout.readline() 

将阻止ioloop运行,因为应用程序将花费其大部分时间在readline()挂了等待写一些输出,而不是应用程序。为了得到这个工作,你将不得不得到stdinstdout的过程(以及stderr? - 你也需要捕获它),将它们切换到非阻塞模式,并将它们添加到文件描述符ioloop花费其时间循环。

+1

您的帖子让我读到了非阻塞IO策略,并且我能够使用[asyncproc](http://www.lysator.liu.se/~bellman/download/asyncproc.py)来处理它。谢谢! – ca4221

+0

太棒了!我担心我的回答太短暂无法提供帮助,很高兴能够让您了解关于异步的知识,以便您可以解决整个问题。如果你有机会,编辑你的问题,并添加一些“这里是解决方案的样子”部分,以便稍后遇到这个问题的人可以看到完整的异步循环是什么样的。 –