9

I have a Python script that is running as a service. It writes to disk. If a user calls systemctl stop on the service, I would like to handle the command in my own way to reduce the risk of file corruption.

How can I catch the systemctl stop command?

My file in /usr/lib/systemd/system is:

[Unit]
Description=foo

[Service]
Type=simple
ExecStart=/usr/bin/python /srv/go.py
User=jon
Restart=always

[Install]
WantedBy=graphical.target

My Python script is:

#!/usr/bin/python

import time
import datetime
import threading

def worker():
    while True:

        with open('/tmp/go.txt', 'a') as f:
            s = str(datetime.datetime.utcnow()) + '\n'
            f.write(s)
            print(s)

            time.sleep(1)


if __name__=='__main__':
    t = threading.Thread(target=worker)
    t.start()
Ginger
  • 8,320
  • 12
  • 56
  • 99
  • maybe this can help with your question? https://stackoverflow.com/questions/18499497/how-to-process-sigterm-signal-gracefully – csim Apr 30 '17 at 22:32
  • Or this: https://stackoverflow.com/questions/1112343/how-do-i-capture-sigint-in-python – languitar Apr 30 '17 at 22:39
  • At first glance, the kill signal isn't the problem... Your thread doesn't have a return/exit condition, and it isn't daemonized so won't automatically go away when the main thread does. Try ```t.daemon = True``` before starting the thread... – MookiBar Feb 01 '21 at 01:10

1 Answers1

21

As described in systemd documentation, processes will receive SIGTERM and then, immediately, SIGHUP. After some time, SIGKILL will be send.

All signals, as well as strategy of sending them, can be changed in relevant service file.

See another stackoverflow question to see how handle these signals in your Python program.

Community
  • 1
  • 1
Mirek Długosz
  • 4,205
  • 3
  • 24
  • 41