0

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.

3
  • Please explain what you’re doing in more detail. What is the purpose of input() in your code? Does it wait for the user’s approval to resume operation? Typically the whole point of a daemon is to run continuously without user interaction. Commented Mar 22, 2019 at 14:03
  • input() function is just to ensure main never ends and callbacks are executed. Similar behavior can be obtained with a busy wait loop --> while True: pass but obviously this loop wastes CPU Commented Mar 22, 2019 at 14:30
  • Do I understand correctly that you want your daemon to device.open() once and then wait for packets indefinitely, running packet_received_callback on each one? Commented Mar 22, 2019 at 14:37

1 Answer 1

2

By its very nature, a daemon cannot input() from the console. You need another way to suspend the main thread indefinitely while letting the XBee PacketListener thread to keep running callbacks.

The easiest way to accomplish this would be to replace input() with:

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

When it’s time to shut down, your system’s service manager will stop your daemon:

  • either by sending SIGTERM — in which case your daemon will terminate immediately, without executing the finally block;
  • or by sending SIGINT — in which case a KeyboardInterrupt exception will bubble out of time.sleep(1000000), and the finally block will run.

In either case, your process should stop quickly.

For a more correct solution, capable also of handling SIGTERM gracefully, see here: https://stackoverflow.com/a/46346184/200445

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.