1

I'm on Ubuntu 18.04.6 LTS and I have a cronjob that schedules automatic shutdown commands to a specific at queue every minute:

$ crontab -e
*/1 * * * * [ -z "$(w -h)" ] && echo "/sbin/shutdown -h now" | at -q w "now + 1 hour"

I now have the problem, that when a machine is stopped by hand between now and +1 hour (meaning there is a job scheduled for execution), and the machine is rebooted the next day, it immediately shuts down again.

It seems that overdue at jobs are executed when the system starts again. Of course this is very annoying, so I thought, I should delete those jobs when the machine starts again.

I created a script that removes all jobs from the queue in /usr/sbin/remove_shutdown_jobs:

#!/bin/bash
jobs=$(atq -q w | cut -f1); if [ -n "$jobs" ]; then atrm $jobs; fi;

And I made it exectuable:

$ ls -lah /usr/sbin/remove_shutdown_jobs
-rwxr-xr-x 1 root root 81 Aug 22 12:06 /usr/sbin/remove_shutdown_jobs

I then tried to link it to the rc5.d directory and gave it the name S00 so that it is executed BEFORE atd is started (my guess is, that I have to remove the jobs before the at daemon is started, otherwise it could pick up those old jobs and execute them):

$ ln -s /usr/sbin/remove_shutdown_jobs /etc/rc5.d/S00remove_shutdown_jobs
$ ln -lah
lrwxrwxrwx   1 root root   30 Aug 31 13:49 S00remove_shutdown_jobs -> /usr/sbin/remove_shutdown_jobs
...
lrwxrwxrwx   1 root root   13 Jun 16 17:21 S01atd -> ../init.d/atd
...

But it seems, that the script is never executed. I tried it with a simple echo script that appends some text to file, and this is also not executed. I thought rc5.d is the right directory, because of

$ runlevel
N 5

I also tried to link it into rc4.d, rc3.d and rc2.d with no luck. I didn't link it to rc1.d because this is only for some kind of rescue system and there where only K01 files in there (kill?), right?

Any idea what I'm missing, or what I've done wrong?

2
  • now I'm wondering why at lets you put things into a queue but atrm does not let you delete by a queue
    – thrig
    Sep 1, 2022 at 15:51
  • yeah, that bothered me too, but the workaround is kinda okay for me
    – 23tux
    Sep 1, 2022 at 17:48

2 Answers 2

1

After reading between the lines, I'm getting the impression that you have an X-Y problem here.

If I understand your intent correctly, Problem X is, "After my system has been up for one hour, I want it to automatically halt after the last user logs out."

Due to the solution you chose for problem X, you now have problem Y which is, "Whenever I boot up, my at queue is full of junk from my system's previous uptime."

I'm going to propose that you eliminate Problem Y by using a cleaner solution to Problem X.

Create a small script that checks whether anyone is logged in, and if so, delays 60 seconds before checking again. Once no one is logged in, halt the system.

# cat << EOF > /root/bin/check-for-halt.sh
#!/usr/bin/env bash

# If anyone is logged in, wait sixty seconds, then check again.
while [ -n "$(w -h)" ] && sleep 60
do
        :
done

# If no one is logged in, halt the system.
[ -z "$(w -h)" ] && /sbin/shutdown -h now
EOF
# chmod 700 /root/bin/check-for-halt.sh

Then replace your crontab line with this one:

@reboot               root    sleep 3600 && /root/bin/check-for-halt.sh

You can adjust the sleep 60 and sleep 3600 values to suit your needs. This method eliminates the need to blow away your at queue on every reboot.

0

To run init script you need to add some preamble like this:

#!/bin/sh
### BEGIN INIT INFO
# Provides:
# Required-Start:    $remote_fs $syslog
# Required-Stop:     $remote_fs $syslog
# Default-Start:     2 3 4 5
# Default-Stop:      0 1 6
# Short-Description: Start daemon at boot time
# Description:       Enable service provided by daemon.
### END INIT INFO

This will give to init subsystem information on which runlevel to run the script. Also you need to provide kind of info how to stop, how to start, etc.

and record in cron like

*/1 * * * * ...

will run, but it is contra intuitive. The clear way is:

* * * * * ...
3
  • 1
    Depending on the system, you should be able to boot from a Live DVD, or into Recovery Mode, or to a Root console. None of those should start crond. Sep 1, 2022 at 14:04
  • Thanks for the answer, I tried adding those comments but unfortunately it didn't work. The script still doesn't run when I boot the machine. Any other ideas?
    – 23tux
    Sep 1, 2022 at 17:57
  • Did you add the script in /etc/rc.d ? Did you exec chkconfig enable ..... Sep 1, 2022 at 17:59

You must log in to answer this question.

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