简体   繁体   中英

Linux: Make systemd kill a running Python script immediately?

I am using systemd on Raspbian to run a Python script script.py . The my.service file looks like this:

[Unit]
Description=My Python Script
Requires=other.service

[Service]
Restart=always
ExecStart=/home/script.py
ExecStop=/home/script.py

[Install]
WantedBy=multi-user.target

When the Required=other.service stops, I want my.service to stop immediately and also terminate Python process running script.py .

However, when trying this out by stopping other.service and then monitoring the state of my.service using systemctl , it seems like it takes good while for my.service to actually enter a ' failed ' state (stopped). It seems that calling ExecStop to the script is not enough to terminate my.service itself and the subsequent script.py in a minute manner.

Just to be extra clear: I want the script to terminate pretty immediately in a way that is analogous to Ctrl + C . Basic Python clean-up is OK, but I don't want systemd to be waiting for a 'graceful' response time-out, or something like that.

Questions:

  1. Is my interpretation of the delay correct, or is it just systemctl that is slow to update its status overview?
  2. What is the recommendable way to stop the service and terminate the script. Should I include some sort of SIGINT catching in the Python script? If so, how? Or is there something that can be done in my.service to expedite the stopping of the service and killing of the script?

I think you should look into TimeoutStopSec and it's default value param DefaultTimeoutStartSec . On the priovided links, there are some more info about WatchdogSec and other options that you might find usefull. It looks like DefaultTimeoutStartSec 's default is 90 seconds, which might be the delay you are experiencing..?

Under unit section options you should use Requisite=other.service This is similar to Requires= However, if the units listed here are not started already, they will not be started and the transaction will fail immediately.

For triggering script execution again under unit section you can use OnFailure= which is a space-separated list of one or more units that are activated when this unit enters the "failed" state.

Also using BindsTo= option configures requirement dependencies, very similar in style to Requires= , however in addition to this behavior, it also declares that this unit is stopped when any of the units listed suddenly disappears. Units can suddenly, unexpectedly disappear if a service terminates on its own choice, a device is unplugged or a mount point unmounted without involvement of systemd.

I think in your case BindsTo= is the option to use since it causes the current unit to stop when the associated unit terminates.

From systemd.unit man

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM