这是处理套接字中数据的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的关闭?
答案 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()