You are not logged in.
Normally, the shutdown sequence will SIGTERM all running service by default.
I am looking for a way to allow a service to finish its job before shutdown completes.
According to the manual, this can be done by using ExecStop to define a command that shuts down the service instead
When I define ExecStop=sleep 30 and issue a shutdown command, it works as expected.
But what I actually want is a simple command that waits for the ExecStart command to finish, which is expected to take around 10 seconds on average
There have been several solutions posted in the past that suggest something like this:
[Unit]
Description=Finish job despite shutdown
[Service]
ExecStart=sleep 30
ExecStop=tail --pid=$MAINPID -f /dev/null
[Install]
WantedBy=multi-user.target
However, when the service is stopped, this fails with the error:
Invalid PID $MAINPID
despite the main PID being listed in the status page even after shutdown.
The manpages mention that "$MAINPID will be unset if systemd knows that the main process exited by the time the stop commands are called" but there is no mention when that is the case.
The only way I found to be working so far is to define the actual main command as ExecStop while ExecStart is simply /bin/true
This is pretty ugly however and I would prefer to do this right, like the service above is intended to do.
Update:
The solution is to execute the tail command inside a separate bash shell like this:
[Unit]
Description=Finish job despite shutdown
[Service]
ExecStart=sleep 30
ExecStop=bash -c 'tail --pid=$MAINPID -f /dev/null'
[Install]
WantedBy=multi-user.target
Last edited by cerino (2025-04-07 20:46:55)
Offline
When I use ExecStop=/bin/kill $MAINPID the service works as expected.
When I use ExecStop=echo $MAINPID it logs the correct PID
Only when I use the command
tail --pid=$MAINPID -f /dev/null
it returns an error about the invalid PID and I cant figure out why that is. Especially since this is a often mentioned solution to wait for the main command to finish.
Someone please tell me what obvious thing I am overlooking...
Offline
I found the solution by using
ExecStop=bash -c 'tail --pid=$MAINPID -f /dev/null'
Why that is necessary in this case but not with the kill command is beyond me but now it works as intended.
Offline