1

I built a little linux-based device that has an eInk screen. It seems that it may increase the lifetime of the screen if I can blank it before the computer shuts down. (EInk passively continues displaying an image even without power, but the image may burn in eventually if it's always the same.) However, blanking the screen takes quite a bit of time on my cheapo display -- about 30 seconds.

I've put my shutdown script in /etc/rc0.d/K01foobar, but it doesn't seem to run. I tried putting in some code at the top of the script to write to a log file, but the log file never gets written to. The script is world executable and has #!/bin/sh at the top.

Any idea what's happening here? Am I using the wrong runlevel? Is the script getting killed before it has time to finish running? Does it not have access to the filesystem in order to write to the log file, because the filesystem has already been shut down by then?

  • most probably it simply doesn't run at all. how are you invoking shutdown procedure? what is the OS? do you have SysVinit, systemd, or other in place? – Bart Jul 5 '19 at 4:27
  • @Bart: The OS is Raspbian, which is a debian derivative. I believe it uses systemd. My understanding was that scripts in the /etc/rc0.d directory would automatically get invoked when the system shut down. (There are other scripts in there.) Is that wrong? – Ben Crowell Jul 5 '19 at 11:53
  • If you believe it use systemd, then don't use all these legacy locations, no matter they're supported or not – 炸鱼薯条德里克 Jul 5 '19 at 13:14
1

I found this blog post, which does a pretty good job of contrasting how this works on SysV and systemd, and explaining how to deal with issues like the filesystem becoming read-only and the command you want to run possibly taking a long time. The following scripts are basically the ones he gives for systemd, with minor modifications.

brownie_shutdown.sh:

#!/bin/bash
# see https://fitzcarraldoblog.wordpress.com/2018/01/13/running-a-shell-script-at-shutdown-only-not-at-reboot-a-comparison-between-openrc-and-systemd/
REBOOT=$( systemctl list-jobs | egrep -q 'reboot.target.*start' && echo "rebooting" || echo "not_rebooting" )
if [ $REBOOT = "not_rebooting" ]; then
  /usr/bin/python /home/pi/Documents/programming/brownie/brownie_blank.py
fi

brownie_shutdown.service:

# see https://fitzcarraldoblog.wordpress.com/2018/01/13/running-a-shell-script-at-shutdown-only-not-at-reboot-a-comparison-between-openrc-and-systemd/
[Unit]
Description=Blank out the eInk screen before shutting down
DefaultDependencies=no
Before=shutdown.target halt.target
# The following is required because my scripts are in /home:
RequiresMountsFor=/home

[Service]
Type=oneshot
ExecStart=/usr/local/sbin/brownie_shutdown.sh

[Install]
WantedBy=halt.target shutdown.target

Makefile:

configure_shutdown:
    cp brownie_shutdown.sh /usr/local/sbin/brownie_shutdown.sh
    chmod +x /usr/local/sbin/brownie_shutdown.sh
    cp brownie_shutdown.service /etc/systemd/system/brownie_shutdown.service
    systemctl enable brownie_shutdown.service

In the bash script, the code at the top is to distinguish between booting and shutting down. In the .service file, the line RequiresMountsFor=/home is there because my scripts are in /home. The ExecStart line points to the bash script. The makefile should be executed as root.

The blog post says you have to reboot for these changes to take effect, but I actually found that they worked immediately when I shut my system down. He talks about the issue of the action possibly taking a long time, which applies to me, and says that other solutions he found online didn't allow his task to run to completion. However, he doesn't explain what feature of his code makes that work correctly.

| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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