2016-03-02 87 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()