How to run a script with systemd right before shutdown?
Solution 1
The suggested solution is to run the service unit as a normal service - have a look at the [Install]
section. So everything has to be thought reverse, dependencies too. Because the shutdown order is the reverse startup order. That's why the script has to be placed in ExecStop=
.
The following solution is working for me:
[Unit]
Description=...
[Service]
Type=oneshot
RemainAfterExit=true
ExecStop=<your script/program>
[Install]
WantedBy=multi-user.target
RemainAfterExit=true
is needed when you don't have an ExecStart
action.
After creating the file, make sure to systemctl daemon-reload
and systemctl enable yourservice --now
.
I just got it from systemd IRC, credits are going to mezcalero.
Solution 2
-
To run a service right before starting any of reboot/shutdown/halt/kexec services (i.e. in the last moment before root filesystem becomes remounted read-only) use this service config:
[Unit] Description=Save system clock on shutdown DefaultDependencies=no After=final.target [Service] Type=oneshot ExecStart=/usr/lib/systemd/scripts/fake-hwclock.sh save [Install] WantedBy=final.target
Enable it with:
systemctl enable my_service.service
-
To run a script right before actual reboot/shutdown/halt/kexec (when you cannot write to the root filesystem, because it was remounted read-only) add this script executable to the
/usr/lib/systemd/system-shutdown
directory.Immediately before executing the actual system halt/poweroff/reboot/kexec systemd-shutdown will run all executables in /usr/lib/systemd/system-shutdown/ and pass one arguments to them: either "halt", "poweroff", "reboot" or "kexec", depending on the chosen action. All executables in this directory are executed in parallel, and execution of the action is not continued before all executables finished.
Also see:
https://www.freedesktop.org/software/systemd/man/bootup.html
https://www.freedesktop.org/software/systemd/man/systemd-halt.service.html
Solution 3
As far as I can see this does what I need (but I don't know exactly why).
[Unit]
Description=Log Traffic
DefaultDependencies=no
Before=shutdown.target reboot.target halt.target
[Service]
ExecStart=/usr/local/bin/perl /home/me/log_traffic.pl --stop
Type=oneshot
Solution 4
I am not totally sure but i don't think you need the install part though i added it explicitly. I also didn't test it but i think it should help you get started:
[Unit]
Description=Log Traffic
Requires=network.target
After=network.target
Before=shutdown.target
DefaultDependencies=no
[Service]
ExecStart=/home/me/so.pl
Type=oneshot
RemainAfterExit=yes
[Install]
WantedBy=shutdown.target
Related videos on Youtube
sid_com
Updated on September 18, 2022Comments
-
sid_com over 1 year
What do I need to put in the
[install]
section, so that systemd runs/home/me/so.pl
right before shutdown and also before/proc/self/net/dev
gets destroyed?[Unit] Description=Log Traffic [Service] ExecStart=/home/me/so.pl [Install] ?
-
sid_com almost 12 yearsWhen I try this the script gets executed soon after the start (boot).
-
sunnysideup almost 12 years@sid_com After reading thread.gmane.org/gmane.comp.sysutils.systemd.devel/4515/… try to add DefaultDependencies=no and maybe remove the install section. Otherwise it may help to remote the after/requires lines.
-
RDP over 8 yearsIt happens to work because of 2 things: 1) DefaultDependencies=no makes it ignores all dependencies and run "at first" on start and "at last" on stop, always respecting "Before" and "After" clauses. 2) It happens to have a Before clause on shutdown/reboot/halt targets, so it will run just before shutdown/reboot/halt is reached on stop (because they only run on stop it happens to do what you want).
-
hanetzer about 8 yearsYou may want to add
kexec.target
to the Before bit -
Bug Killer over 7 yearsThis doesn't work for me
-
rsaw over 7 yearsI don't see how this will work unless you also add
WantedBy=shutdown.target reboot.target halt.target
to the[Unit]
section.Before=
&After=
don't change dependencies. -
niels over 7 yearsAt ubuntu 16.04 you must have a
ExecStart=/bin/true
. -
Mcol almost 7 yearsMy assumption to WHY
RemainAfterExit=true
is required when there is noExecStart
is becausesystemd
will not attempt to runExecStop
if it thinks that the service is not running.RemainAfterExit=true
causessystemd
to believe that the service is running, thereby causing it to runExecStop
at shutdown. -
richmb over 6 yearsIs there anyway to ensure this script will run and complete before user sessions and user processes are terminated?
-
svenwltr over 6 years@richmb Not at all. From the docs:
Note that it is usually not sufficient to specify a command for this setting that only asks the service to terminate (for example, by queuing some form of termination signal for it), but does not wait for it to do so.
-
2rs2ts over 5 yearsI've tried this and various iterations on it but it does not work on Debian Stretch.
-
2rs2ts over 5 yearsThis answer doesn't solve the problem where you need something to run before other things shut down
-
waitfor almost 5 yearsI want to execute something as near as possible after initiating a reboot, way before the
final.target
. Ideally I would like that it is the first thing being executed after the user do$ sudo reboot
. -
Charles Duffy over 4 years@2rs2ts, can you clarify "does not work" with more specificity? Does the service not load? Does its
ExecStop
begin execution but get killed before the process is able to complete? Something else? -
Aspiring Dev about 4 yearsIt seems you still have to add
ExecStart=/bin/true
for this to work, addingRemainAfterExit=true
(withoutExecStart
) was not enough for me to get this to work on Fedora. -
maxschlepzig almost 4 yearsI tested the first approach on RHEL 7 and the service is actually executed after the root-filesystem is remounted read-only. That means hwclock state can't be written to
/etc/adjtime
then. This behavior is also what I expected after looking at the linked chart - because theumount.target
readonly-remounts the root filesystem andfinal.target
depends on that target. -
ImranRazaKhan almost 4 years@JaimeHablutzel Are you able to achieve?