3

Background

I'm trying to write a script (see end of the question) that checks the temperature on Raspberry PI and shuts it down automatically if it goes too high. The script would be run by cron, once a minute, as root.

The problem

The script is executed, the message is printed as expected, but the shutdown is not scheduled, and there is no error message about why. Indeed after cron runs the script, cat /run/systemd/shutdown/scheduled shows nothing (file does not exist). However, after running the script manually, (still as root), cat /run/systemd/shutdown/scheduled shows that the shutdown is indeed scheduled.

Question

Why does the script work, when invoked manually, but not when invoked by cron (even though it is in root's crontab)?

Related

This question is similar, but the conclusion of the answers seems to be that adding shutdown to root's crontab (via crontab -e as I do) should be fine.

Details

The script: /root/shutdown_overheat.sh

#!/bin/sh

MAXTEMP=30         # temporarily lowered for testing
TEMP=$(/opt/vc/bin/vcgencmd measure_temp | awk -F'[=.]' '{print $2}')
MSG="Temperature $TEMP higher than $MAXTEMP, shutting down in 2 minutes"

if [ "$TEMP" -gt "$MAXTEMP" ]; then
        wall $MSG
        logger System $MSG
        shutdown -h +2 $MSG
fi

Running the script manually (as root):

# ./shutdown_overheat.sh 

Broadcast message from attilio@kolcsag (pts/0) (Fri Mar 13 20:41:13 2020):     

Temperature 54 higher than 30, shutting down in 2 minutes

Shutdown scheduled for Fri 2020-03-13 20:43:13 GMT, use 'shutdown -c' to cancel.
# cat /run/systemd/shutdown/scheduled 
USEC=1584132193792504
WARN_WALL=1
MODE=poweroff
WALL_MESSAGE=Temperature 54 higher than 30, shutting down in 2 minutes

Script executed by cron:


Broadcast message from root@kolcsag (somewhere) (Fri Mar 13 20:42:01 2020):    

Temperature 54 higher than 30, shutting down in 2 minutes

# cat /run/systemd/shutdown/scheduled 
cat: /run/systemd/shutdown/scheduled: No such file or directory

Root's crontab:

# crontab -l



# Edit this file to introduce tasks to be run by cron.
# 
# ... etc

* * * * * /root/shutdown_overheat.sh
4
  • Any errors emailed to root by the cron daemon?
    – Kusalananda
    Mar 13 '20 at 21:16
  • I don't know: where can I check that?
    – Attilio
    Mar 13 '20 at 21:19
  • In root's mailbox?
    – Kusalananda
    Mar 13 '20 at 23:07
  • 1
    it could be a path issue, try specifying the full path to shutdown. And/or try putting it in /etc/crontab. And/or try using poweroff instead of shutdown.
    – gogoud
    Mar 14 '20 at 19:58
0

Kusalananda and gogoud are right. You should check cron mail.

Short answer

Replace:

if [ "$TEMP" -gt "$MAXTEMP" ]; then
        wall $MSG
        logger System $MSG
        shutdown -h +2 $MSG
fi

with:

if [ "$TEMP" -gt "$MAXTEMP" ]; then
        wall $MSG
        logger System $MSG
        /usr/sbin/shutdown -h +2 $MSG
fi

Or where ever your binary is (whereis -b shutdown).

Long answer

I was trying to implement cron-apt and reboot if /var/run/reboot-required exists. I had all my expected log messages in journald, but reboot would not work. Here is what I had in cron.d where cron-apt puts its definitions. I separated everything into a custom script, similar to what you did. The second line was just for testing.

$ sudo cat /etc/cron.d/cron-apt
45 3 * * *  root  "/usr/local/bin/cron-apt-server"
*/10 * * * *  root  "/usr/local/bin/cron-apt-server"

Before trying every 10 minutes I tried cron.hourly:

$ sudo ln -sf /usr/local/bin/cron-apt-server /etc/cron.hourly/

That worked! Now I was even more confused!

I recreated the files checked by my script: sudo touch /var/run/reboot-required{,.pkgs}; echo test | sudo tee -a /var/run/reboot-required.pkgs

And tested cron.d again. Then noticed journalctl -f telling me about mail right after my cron job:

Mär 10 14:35:24 studentvm1 cron-apt-server[5260]: Rebooting for packages: test
Mär 10 14:35:24 studentvm1 CRON[3037]: pam_unix(cron:session): session closed for user root
Mär 10 14:35:24 studentvm1 postfix/pickup[1998]: A4346601AA6: uid=0 from=<root>
Mär 10 14:35:24 studentvm1 postfix/cleanup[5264]: A4346601AA6: message-id=<20210310133524.A4346601AA6@ubuntu-server>
Mär 10 14:35:24 studentvm1 postfix/qmgr[1999]: A4346601AA6: from=<root@ubuntu-server>, size=1444, nrcpt=1 (queue active)

Postfix just mailed me, or root.

$ sudo mail
Mail version 8.1.2 01/15/2001.  Type ? for help.
"/var/mail/root": 21 messages 21 new

[...]

 N 21 root@ubuntu-serve  Wed Mar 10 14:30   38/1551  Cron <root@studentvm1>  "/usr/local/bin/cron-apt-server"

Whoops we ignored 21 messages. Let's open the last one.

& 21

Message 21:
From root@ubuntu-server  Wed Mar 10 14:30:01 2021
X-Original-To: root
From: root@ubuntu-server (Cron Daemon)
To: root@ubuntu-server
Subject: Cron <root@studentvm1>  "/usr/local/bin/cron-apt-server"
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
X-Cron-Env: <SHELL=/bin/sh>
X-Cron-Env: <HOME=/root>
X-Cron-Env: <PATH=/usr/bin:/bin>
X-Cron-Env: <LOGNAME=root>
Date: Wed, 10 Mar 2021 14:30:01 +0100 (CET)

[...]

+ [[ -f /var/run/reboot-required ]]
+ [[ server == \s\e\r\v\e\r ]]
++ cat /var/run/reboot-required.pkgs
+ msg='Rebooting for packages: test'
+ logger_notice 'Rebooting for packages: test'
+ logger -p notice -t cron-apt-server 'Rebooting for packages: test'
+ shutdown -r now 'Rebooting for packages: test'
/usr/local/bin/cron-apt-server: line 66: shutdown: command not found

& q

And there I had it: line 66: shutdown: command not found I replaced shutdown with /usr/sbin/shutdown and it worked!

The lines prefixed with + are generated by set -x which I set for debugging.

Edit: See also https://askubuntu.com/a/13733/40581

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.