Фон
Я пытаюсь написать скрипт (см. конец вопроса), который проверяет температуру Raspberry PI и автоматически выключает его, если она становится слишком высокой. Скрипт будет запускаться cron раз в минуту,как корень.
Проблема
Скрипт выполняется, сообщение выводится, как и ожидалось, но выключение не запланировано, и нет сообщения об ошибке о причине. Действительно, после того, как cron запускает скрипт, cat /run/systemd/shutdown/scheduled
ничего не показывает (файл не существует). Однако после запуска скрипта вручную (все еще как root) cat /run/systemd/shutdown/scheduled
показывает, что выключение действительно запланировано.
Вопрос
Почему скрипт работает при ручном запуске, но не работает при запуске через cron (хотя он находится в crontab пользователя root)?
Связанный
Этот вопроспохоже, но вывод из ответов, похоже, таков, что добавление выключения ккорнеплодыcrontab (через crontab -e
, как я) должен подойти.
Подробности
Сценарий:/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
Запуск скрипта вручную (как 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
Скрипт, выполняемый 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
Crontab пользователя Root:
# crontab -l
# Edit this file to introduce tasks to be run by cron.
#
# ... etc
* * * * * /root/shutdown_overheat.sh
решение1
Кусалананда и Гогуд правы. Вам следует проверитьпочта cron.
Короткий ответ
Заменять:
if [ "$TEMP" -gt "$MAXTEMP" ]; then
wall $MSG
logger System $MSG
shutdown -h +2 $MSG
fi
с:
if [ "$TEMP" -gt "$MAXTEMP" ]; then
wall $MSG
logger System $MSG
/usr/sbin/shutdown -h +2 $MSG
fi
Или где бы ни находился ваш двоичный файл ( whereis -b shutdown
).
Длинный ответ
Я пытался реализоватьcron-aptи перезагрузка, если /var/run/reboot-required
существует. У меня были все мои ожидаемые сообщения журнала в journald, но перезагрузка не работала. Вот что у меня было в cron.d, куда cron-apt помещает свои определения. Я выделил все в пользовательский скрипт, похожий на тот, что сделали вы. Вторая строка была просто для тестирования.
$ sudo cat /etc/cron.d/cron-apt
45 3 * * * root "/usr/local/bin/cron-apt-server"
*/10 * * * * root "/usr/local/bin/cron-apt-server"
Прежде чем пробовать каждые 10 минут, я попробовал cron.hourly:
$ sudo ln -sf /usr/local/bin/cron-apt-server /etc/cron.hourly/
Это сработало! Теперь я был еще больше запутан!
Я пересоздал файлы, проверенные моим скриптом:sudo touch /var/run/reboot-required{,.pkgs}; echo test | sudo tee -a /var/run/reboot-required.pkgs
И снова протестировал cron.d. Потом заметил, что journalctl -f
сразу после моего задания cron он сообщает мне о почте:
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 или 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"
Упс, мы проигнорировали 21 сообщение. Давайте откроем последнее.
& 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
И вот я это сделал: line 66: shutdown: command not found
заменил shutdown
на /usr/sbin/shutdown
и все заработало!
Строки с префиксом +
генерируются с помощью set -x
, который я установил для отладки.
Редактировать: См. такжеhttps://askubuntu.com/a/13733/40581