How do I run a script before everything else on shutdown with systemd?
Solution 1
I got it!
Take solution Long running process with StopExec and modify it like so:
autobackup.service:
[Unit]
Description=Slow backup script
RequiresMountsFor=/mnt/BACKUP /home
[Service]
ExecStop=/etc/systemd/system/do_backup.sh
Type=oneshot
RemainAfterExit=yes
[Install]
WantedBy=multi-user.target
Note the line:
RequiresMountsFor=/mnt/BACKUP /home
It works as expected this way.
Solution 2
No need to create or edit service files. Simply drop your script in
/usr/lib/systemd/system-shutdown/
https://www.freedesktop.org/software/systemd/man/systemd-halt.service.html
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.
I use it to simply beep the PC speaker.
Related videos on Youtube
le_me
Updated on September 18, 2022Comments
-
le_me over 1 year
Note: Briefly formulated question can be found at the bottom.
I have a script which makes a backup of my files onto an external USB drive. Executing it can take a while, depending on the amount of new data I've created. I want to run it automatically on every shutdown of the system.
I'm using fedora 23 with latest updates (systemd).
I tried to achieve this in several ways, but I couldn't get it to work.
Long running process with StopExec
autobackup.service:
[Unit] Description=Slow backup script Requires=local-fs.target [Service] ExecStart=/bin/true ExecStop=/etc/systemd/system/do_backup.sh Type=oneshot RemainAfterExit=yes [Install] WantedBy=multiuser.target
I activated it with
systemctl enable autobackup.service
and started it withsystemctl start autobackup.service
.Part of my boot log (
journalctl -b-1
):Dez 22 17:45:27 localhost systemd[1]: Unmounted /mnt/BACKUP. Dez 22 17:45:27 localhost do_backup.sh[4296]: At subvol /home/BACKUP.2015_12_22-17_45_25 Dez 22 17:45:27 localhost do_backup.sh[4296]: ERROR: parent subvol is not reachable from inside the root subvol. Dez 22 17:45:27 localhost do_backup.sh[4296]: At snapshot BACKUP.2015_12_22-17_45_25 Dez 22 17:45:27 localhost do_backup.sh[4296]: ERROR: failed to dump stream. Broken pipe Dez 22 17:45:27 localhost systemd[1]: autobackup.service: Control process exited, code=exited status=1 Dez 22 17:45:27 localhost systemd[1]: Stopped Slow backup script. Dez 22 17:45:27 localhost systemd[1]: autobackup.service: Unit entered failed state.
Note that I didn't shorten anything in between, it really unmounted /mnt/BACKUP just before the script started, funny coincidence..
Before shutdown.target
autobackup.service:
[Unit] Description=Slow backup script DefaultDependencies=no Before=shutdown.target [Service] ExecStart=/etc/systemd/system/do_backup.sh Type=oneshot
systemctl edit shutdown.target
[Unit] Requires=autobackup.service
Output is basically the same.
The Problem
I think the problem is that systemd starts my script in parallel with all the other shutdown scripts in both cases, which unmount BACKUP and deactivate the pipe infrastructure (another error I sometimes got, when the unmount wasn't fast enough).
The Question
How can I teach systemd to start my script first on shutdown, wait until it exits and then start the rest of the shutdown scripts/targets/units/whatever?
-
Stefan Majewsky about 8 yearsYou shouldn't need to do the
systemctl edit
.systemctl enable autobackup
has the same effect and is more idiomatic, and should work since you already have the[Install]
section in your unit. You will have to correct that typo in the target name, though. ;) -
WoJ over 7 yearsDid you have to make this directory? I do not have it neither on Ubuntu 16.04 nor Raspbian (jessie) - both are systemd based.
-
Frank Breitling about 7 yearsDebian systems use the different path
/lib/systemd/system-shutdown/
. And in addition be aware that these scripts are executed very late in shutdown, after file systems are already mounted read-only. So any write access to the file system will fail unless remounted as read-write (mount -oremount,rw /
). See How to execute scripts in /usr/lib/systemd/system-shutdown/ at reboot or shutdown? -
Greg Alexander about 7 yearsOP asked for script executed "before everything else" on shutdown. The system-shutdown scripts are executed after everything else, immediately before killing the kernel.
-
2rs2ts over 5 yearsThis does not work for me. I don't have any mounts, I just want to make sure my script runs before other units shut down.