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]
?
up vote 56 down vote accepted

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.

  • 6
    At ubuntu 16.04 you must have a ExecStart=/bin/true. – niels Dec 29 '16 at 20:50
  • 2
    My assumption to WHY RemainAfterExit=true is required when there is no ExecStart is because systemd will not attempt to run ExecStop if it thinks that the service is not running. RemainAfterExit=true causes systemd to believe that the service is running, thereby causing it to run ExecStop at shutdown. – Felipe Alvarez Jun 15 '17 at 0:30
  • 1
    Is there anyway to ensure this script will run and complete before user sessions and user processes are terminated? – richmb Oct 19 '17 at 13:19
  • @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. – svenwltr Nov 30 '17 at 11:19
  • I've tried this and various iterations on it but it does not work on Debian Stretch. – 2rs2ts Sep 21 at 1:02

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
  • 3
    It 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). – RDP Jan 29 '16 at 1:01
  • You may want to add kexec.target to the Before bit – hanetzer Mar 26 '16 at 11:11
  • This doesn't work for me – Bug Killer Sep 7 '16 at 1:50
  • I 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. – rsaw Sep 8 '16 at 15:57
  • 1
    @FelipeAlvarez: I have removed my comment. – sid_com Jun 22 at 4:07

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
  • 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

protected by Stephen Kitt Jul 28 '17 at 9:42

Thank you for your interest in this question. Because it has attracted low-quality or spam answers that had to be removed, posting an answer now requires 10 reputation on this site (the association bonus does not count).

Would you like to answer one of these unanswered questions instead?

Not the answer you're looking for? Browse other questions tagged or ask your own question.