10

I want a simple python script to run in background, therefore I configured daemon test.service in /etc/systemd/system/.

[Unit]
Description=Test service
After=multi-user.target

[Service]
Type=simple
ExecStart=/usr/bin/python /home/pi/daemon.py
Restart=on-abort

[Install]
WantedBy=multi-user.target

My executing script daemon.py toogles a LED controlled by a button.

#!/usr/bin/python

import RPi.GPIO as GPIO
GPIO.setmode(GPIO.BCM)

# Configure button pin
GPIO.setup(14, GPIO.IN, pull_up_down=GPIO.PUD_UP)
# Configure LED pin
GPIO.setup(18, GPIO.OUT)

def button1(channel):
    print "Toogle LED!"
    GPIO.output(18, not GPIO.input(18))

GPIO.add_event_detect(14, GPIO.FALLING, callback=button1, bouncetime=300)

try:
    while True:
        pass

finally:
    print "cleanup() GPIOs"
    GPIO.cleanup()

Now, I can start my script as a service with systemctl start test.service and stop it the same way. But for a clean script, I want to execute GPIO.cleanup() before the script is closed by systemctl stop test.service. How can I achieve that? The finally doesn't seem to work in this case...

Secondly, all the print messages like "Toogle LED!" cannot be seen when I call systemctl status test.service. Is the output written to another file somewhere else?

Thank you for your help in advance!

Ingo
  • 42,961
  • 20
  • 87
  • 207
EarlyEarl
  • 103
  • 1
  • 5

2 Answers2

10

Now, I can start my script as a service with systemctl start test.service and stop it the same way. But for a clean script, I want to execute GPIO.cleanup() before the script is closed by systemctl stop test.service. How can I achieve that? The finally doesn't seem to work in this case...

By default, systemd sends a SIGTERM, then SIGKILL to your service unless you've specified more complex logic. SIGTERM doesn't raise an exception in Python, so your finally block probably doesn't get run.

Try adding:

KillSignal=SIGINT

Below [Service] to tell systemd to send a SIGINT, which is translated as a KeyboardInterrupt exception by Python. This should then run your graceful exit logic.

Secondly, all the print messages like "Toogle LED!" cannot be seen when I call systemctl status test.service. Is the output written to another file somewhere else?

Yes, you should use:

journalctl -u test.service

This will read the systemd journal logs for your service. status just gives you a brief summary of whether your service is functioning; it's not the full log.

Aurora0001
  • 6,357
  • 3
  • 25
  • 39
3

You can also do it using the signal native Python package:

def exit_gracefully(signum, frame):
    logging.info('Exited')

signal.signal(signal.SIGTERM, exit_gracefully)
Stefan Wegener
  • 297
  • 1
  • 2
  • 12
user5365075
  • 131
  • 3