How to run a script with systemd right before shutdown?

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.


  • 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


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