如何在龙卷风循环中侦听闭合标准输入的事件?

时间:2016-03-02 07:56:47

标签: python tornado

这是处理套接字中数据的follow-up question。但是,我无法捕捉" 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

我如何监听stdin的关闭?

1 个答案:

答案 0 :(得分: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()