0

I have a script that I want to execute before a machine is either shut down or rebooted but it's only triggered with the start parameter, never with the stop parameter and it's driving me crazy.

Following symlinks exist on my system:

/etc/rc0.d/K01init.sh
/etc/rc1.d/K01init.sh
/etc/rc2.d/S99init.sh
/etc/rc3.d/S99init.sh
/etc/rc4.d/S99init.sh
/etc/rc5.d/S99init.sh
/etc/rc6.d/K01init.sh

that all point to the same script /etc/init.d/init.sh. Based on another thread I also tried without the .sh suffix, which did not change anything.

/etc/init.d/init.sh

#!/bin/sh
### BEGIN INIT INFO
# Provides:          init.sh
# Required-Start:    $all
# Required-Stop:
# Default-Start:     2 3 4 5
# Default-Stop:      0 1 6
# Short-Description: xxx
# Description:       xxx
### END INIT INFO

if [ "$1" = "start" ]; then
  echo "log message"
  //do stuff
fi

echo "$1"

if [ "$1" = "stop" ]; then
  echo "log message"
  //do stuff
fi

exit 0

The script runs fine during startup, but complains that the cleanup that should have happened in the stop block was not performed. When I echo the $1 to the logs, it only and always shows start, which means the OS apparently never sends the stop command to my script. Running the script from the command line (sudo /etc/init.d/init.sh stop) works like a charm with both start and stop parameters, so I'm confused as to why it does not work when I stop my machine.

Where am I going wrong here? I'm running Ubuntu 18.04 and my current runlevel is 5 (but that should not be relevant, as it should be about 0 & 6 here). Interesting enough, I tried to check for the actual runlevel at execution time by adding echo "$(who -r)" to the script, which does not output anything to the logs!

If relevant: I'm talking about reboots both via sudo reboot / sudo systemctl reboot and via Azure GUI (it's a virtual machine), not sure if Azures reboot mechanism differs, but neither way works.

2 Answers 2

1

You should get to know about systemd, which has replaced old runlevels and init system.

systemd still can run old init.d scripts, but I would recommend you learn a bit of systemd and write a systemd service file. First take a look here How does systemd use /etc/init.d scripts?, where you can find some description about systemd handling init.d.

My guess would be that your script is not being executed on shutdown, because systemd does not consider it running. Maybe your script is something that is executed and then exits. It does not run all the time. systemd detects that and the script is not in running state. If is exists, it does not run. Therefore, systemd does not stop it, because there is nothing to stop.

Check the status with systemctl command and see what does is say about your service. You can just type systemctl and look for your script. You can also try

systemctl status init.sh
systemctl start init.sh
systemctl stop init.sh
systemctl restart init.sh

These are command that are actually executed, and not the old init.d script.

I would recommend migrating to systemd. Look at service unit configuration (https://www.freedesktop.org/software/systemd/man/systemd.service.html). Maybe the best type of your service would be oneshot. You can find an example here How to run a script with systemd right before shutdown?. According to the examlpe, you should create something like this /etc/systemd/system/init.sh.service:

[Unit]
Description=init.sh

[Service]
Type=oneshot
RemainAfterExit=true
ExecStart=/etc/init.d/init.sh start
ExecStop=/etc/init.d/init.sh stop

[Install]
WantedBy=multi-user.target

Then enable your service in systemd:

sudo systemctl enable init.sh.service

If you want to control more precisely, when your service should be started, you can add After=, Before=. There are lot of other options, too.

0

I suspect that the lack of value on the Required-Stop: is the issue. You are telling it that you don't need anything else running when you stop, like the logger and the disks. Add the parameter to match the Required-Start: line.

You should also be more descriptive in your name. There is a standard service "init" -- it is the parent of the thing that will run your script.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .