0

So I have a Raspberry Pi 3B+ running Raspberry OS on Xfce GUI.

I'm trying to run a script on shutdown using the advice given on this thread.

[Unit]
Description=Screensaver

[Service]
Type=oneshot
RemainAfterExit=true
ExecStart=/bin/true
ExecStop=/usr/local/bin/image.sh

[Install]
WantedBy=multi-user.target

The script is placed at /etc/systemd/system/

It works on reboot but it doesn't on shutdown. I can't understand why.

Running systemctl cat img.service gives me this output:

[Unit]
Description=Screensaver

[Service]
Type=oneshot
RemainAfterExit=true
ExecStart=/bin/true
ExecStop=/usr/local/bin/image.sh

[Install]
WantedBy=multi-user.target

Basically the same thing. I'm a new Linux user so I'm pretty much lost.

I've also tried placing the script on the system-shutdown folder as suggested on this thread.

I don't know where to start to solve this, but any guidance would be of great help. I've tried researching on this forum but I don't see any other possible answers to this issue. Hope someone can help.

EDIT: I've tried changing the .service file to this:

[Unit]
Description=Screensaver
After=multi-user.target

[Service]
Type=oneshot
RemainAfterExit=true
ExecStart=/usr/local/bin/image.sh

[Install]
WantedBy=halt.target
WantedBy=reboot.target

Following the provided answer didn't work. In fact, my e-ink screen stopped working (the script I'm using basically sends a screensaver image to a e-ink Waveshare screen) until I disabled the systemctl. n I ran systemctl status and this is the output I got. Which means it worked but not in time before shutdown, I guess? Maybe it just keeps running continuously and that's why any interfering/parallel commands don't work anymore?

● img.service - Screensaver
     Loaded: loaded (/etc/systemd/system/img.service; enabled; vendor preset: enabled)
     Active: activating (start) since Thu 2024-01-25 21:42:11 CET; 4min 56s ago
   Main PID: 989 (image.sh)
      Tasks: 3 (limit: 1595)
        CPU: 6.686s
     CGroup: /system.slice/img.service
             ├─ 989 /bin/bash /usr/local/bin/image.sh
             ├─ 998 sudo papertty_venv/bin/papertty --driver IT8951 image --rotate 0 --stretch --image ./Pictures/sleep.bmp
             └─1025 /home/javierdepascual/papertty_venv/bin/python3 papertty_venv/bin/papertty --driver IT8951 image --rotate 0 --stretch --image ./Pictures/sleep.bmp

Jan 25 21:42:11 raspberrypi systemd[1]: Starting Screensaver...
Jan 25 21:42:11 raspberrypi sudo[998]:     root : PWD=/home/javierdepascual ; USER=root ; COMMAND=papertty_venv/bin/papertty --driver IT8951 image --rotate 0 --stretch --image ./Pictures/sleep.bmp
Jan 25 21:42:11 raspberrypi sudo[998]: pam_unix(sudo:session): session opened for user root(uid=0) by (uid=0)

1 Answer 1

2

Run a script at shutdown on Raspbian

That's not a very good answer IMO. Manually placing stuff in sysd target directories might be okay if you are familiar with how it all works and you are fiddling around, but it is not really the proper/correct method.

Since you aren't doing this properly, this part of the service file is totally irrelevant, symptomatic of cargo-cultism:1

[Install]
WantedBy=multi-user.target

To be fair, you don't know you are getting poor advice and unfortunately these things are on this site :\

What's particularly bad here is that if at some point you ran across more correct instructions (using enable as below), you'd end up with something that runs at boot instead (see footnote 2 below about how there are essentially two different methodologies at cross purposes here).

Anyway, replace that with

[Install]
WantedBy=halt.target
WantedBy=reboot.target

Replace the ExecStart line with the ExecStop line and remove the latter, so there is just:

ExecStart=/usr/local/bin/image.sh

Place the script in /etc/systemd/system. This is not a target directory referred to above, but you will see them there (directories with the .target.wants suffix).

Then:

sudo systemctl enable whatever.service

Where "whatever.service" is the name of the file you placed in /etc/systemd/system. Double check there is a symlink to it in the halt.target.wants and reboot.target.wants subdirectories.2 You can also use systemctl status whatever.service to check that and subsequently on reboot to see if it ran at last shutdown.


  1. Something that happens easily when someone who doesn't really know what they are doing takes advice from someone else who doesn't really know what they are doing, but it works in some particular circumstance, then later that person passes it on to someone else, which can compound problems telephone game style.

  2. If you had your original WantedBy and used enable, they'd end up in multi-user.target.wants, which is for things that run at boot. This is why whoever wrote that uses the dud ExecStart=/bin/true, and RemainAfterExit=true, so that ExecStop would be run at shutdown. Hence it is probably not the same person that recommended this then be put in the shutdown directory, since then only the ExecStart dud would run, doing nothing.

3
  • Thank you so much for clarifying, I'm trying to understand but as a new linux user it's very difficult for me to be able to figure it out and, as you said, there's a lot of misleading information out there, unfortunately. However, it doesn't work, even though the output from the status command seems to tell that everything's fine. I would paste it but it seems like it's too long for a comment. Commented Jan 25 at 20:37
  • You need to add some logging to the script to help you debug the problem; right now if you are not catching any exceptions the system might be; try journalctl -xeu [whatever]. WRT the linux learning curve and misleading information, 1) When you are searching for info, use "linux" and not "raspberry pi" (at first, anyway). Pi users have formed a bit of an online echo chamber and it is not all good; 2) Try to corroborate what you find with the relevant man pages. Systemd alone has almost 400 of them...
    – goldilocks
    Commented Jan 26 at 14:08
  • ...They are a bit like API documentation in that they are intended as references/primary sources (vs. tutorials or secondary sources intended to facilitate learning), but once you are used to them, like API docs they're literally invaluable. WRT systemd, man systemd.directives lists all the directives (such as WantedBy=) together with the name of the man page they are documented in. You can search within the man page viewer via the / (which is a standard thing with *nixy tools). WRT script logging, have a look at the StandardOutput and StandardError sysd directives.
    – goldilocks
    Commented Jan 26 at 14:08

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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