2016-03-02 52 views
1

这是处理套接字中数据的follow-up question。但是,我无法捕获“stdin closed”事件。这是我现在有:如何监听龙卷风循环中关闭的stdin事件?

import sys 
import tornado 

from tornado.ioloop import IOLoop 
from tornado.web import Application, RequestHandler 

class MainHandler(RequestHandler): 
    def get(self): 
     self.finish("foo") 
application = Application([ (r"/", MainHandler), ]) 

@tornado.gen.coroutine 
def close_callback(*args, **kwargs): 
    print args, kwargs 

if __name__ == "__main__": 
    application.listen(8888) 

    stdin = tornado.iostream.PipeIOStream(sys.stdin.fileno()) 
    stdin.set_close_callback(close_callback) 

    IOLoop.instance().start() 

和测试:

$ ./tornado_sockets.py # expect to close stdin 
<C-d> # nothing happens 

另一项测试:

$ echo expect_stdin_to_be_closed | ./tornado_sockets.py 
# nothing happens 

我如何可以监听标准输入的结束?

回答

1

报价sys.stdin does not close on ctrl-d

Ctrl键 + d具有奇怪的效果。它不会关闭输入流,但只会导致C级fread()返回空结果。

所以基本上你需要用空字符串断言读线。例如一些无PipeIOStream

from tornado.ioloop import IOLoop 
import sys 

def on_stdin(fd, events): 
    line = fd.readline() 
    print("received: %s" % repr(line)) 
    if line == '': 
     print('stdin ctr+d') 
     sys.exit() 

if __name__ == "__main__": 
    IOLoop.instance().add_handler(sys.stdin, on_stdin, IOLoop.READ) 
    IOLoop.instance().start() 

随着PipeIOStream它使用read_until_close是非常简单的。回拨将在关闭或拨打电话Ctrl + D

import sys 
import tornado 
import tornado.iostream 
from tornado.ioloop import IOLoop 
from functools import partial 

def read(stdin, data): 
    print(data) 
    # below lines are unnecessary they are only for testing purposes 
    stdin.close() 
    IOLoop.instance().stop() 

if __name__ == "__main__": 
    stdin = tornado.iostream.PipeIOStream(sys.stdin.fileno()) 
    stdin.read_until_close(callback=partial(read, stdin)) 
    IOLoop.instance().start()