首页 > 解决方案 > python script fails running as a daemon (EOFError: EOF when reading a line)

问题描述

I've created a python3 script that runs fine on command line but when I try to run as a daemon in MacosX gives error 'EOFError: EOF when reading a line'. Basically code is as follows:

  (...)

  def main():

    # Connect
    port, speed = connect_port()

    device = XBeeDevice(port, speed)

    try:
      device.open()
      # print("Waiting for data...\n")

     (...)

      device.add_packet_received_callback(packet_received_callback)
      input()

    finally:
      if device is not None and device.is_open():
        device.close()

  if __name__ == '__main__':
    main()

plist seems to be fine as script starts and runs once before to give error:

Traceback (most recent call last):
File "/maslestorres.cat/jardiNet_datalogger.py", line 214, in <module>
main()
File "/maslestorres.cat/jardiNet_datalogger.py", line 206, in main
input()
EOFError: EOF when reading a line

So basically I don't know how to adapt the input() line to allow to run as a daemon. Python is version 3.7.2 and MacOSX is 10.8.5.

标签: pythonpython-3.xmacoslaunchd

解决方案


就其本质而言,守护进程不能input()来自控制台。您需要另一种方法来无限期地挂起主线程,同时让 XBeePacketListener线程继续运行回调。

完成此操作的最简单方法是替换input()为:

while True:
    time.sleep(1000000)    # arbitrarily large number

当需要关闭时,系统的服务管理器将停止您的守护进程:

  • 要么通过发送SIGTERM——在这种情况下,你的守护进程将立即终止,而不执行finally块;
  • 或者通过发送SIGINT——在这种情况下,一个KeyboardInterrupt异常会从 中冒出来time.sleep(1000000),并且该finally块将运行。

无论哪种情况,您的进程都应该快速停止。

有关更正确的解决方案,也能够SIGTERM优雅地处理,请参见此处:https ://stackoverflow.com/a/46346184/200445


推荐阅读