Ubuntu Server 26.04は実験環境であるので、常時起動しておく必要はない。
作業完了時に自分でシャットダウンしてもよいが、切り忘れ対策として自動シャットダウンを仕込むことにした。
システムの稼働時間が一定以上になり、かつ以下の条件で「無人・無負荷状態」が継続した場合に、自動でシャットダウンを実行する。
ただ、上記の条件だと日次で実行してほしい処理が、全く実行されないまま停止してしまう可能性がある。
そこで日次処理を行うanacronの処理が済んだあとに実行する条件を追加した。
日次処理実行済みのフラグ作成はanacronの処理の最後になるよう、アルファベットのzが連続するファイル名でスクリプトを作成する。
日次処理済のフラグを作成するスクリプト
#!/bin/sh
zzz=/var/local/zzz
touch ${zzz}
自動シャットダウンのスクリプトをcronで任意の間隔(10-60分)で実行する。
cron設定の例
1,11,21,31,41,51 * * * * root /usr/local/sbin/auto-poweroff.sh 1>/dev/null 2>/dev/null
自動シャットダウン スクリプト
#!/bin/sh
#
# Auto-poweroff
#
timeup=3600
overtime=1800
lastlog=/var/local/ltime
zzzflg=/var/local/zzz
#
btime=`sed -e 's/btime *//p;d' /proc/stat`
uptime=$(expr "$(cat /proc/uptime)" : '\([0-9]*\)')
ctime=$(expr ${btime} + ${uptime})
users=$(loginctl list-users --no-legend | wc -l)
pty=`cat /proc/sys/kernel/pty/nr`
tcp=`awk 'BEGIN {c = 0} {if ($4 == "01") c++} END {print c}' /proc/net/tcp`
cpu=`fgrep -c 'processor' /proc/cpuinfo`
loadavg=$(expr "$(cat /proc/loadavg)" : '\([0-9]*\)')
load=$(expr ${loadavg} / ${cpu})
zzz=$(test -f ${zzzflg} && echo 1 || echo 0)
#
if [ ${uptime} -le ${timeup} ]
then
echo "Uptime is within the time limit.(${timeup}sec)" 1>&2
if [ -f ${lastlog} ]
then
if [ -f ${zzzflg} ]
then
test ${zzzflg} -ot ${lastlog} && rm ${zzzflg}
fi
rm ${lastlog}
fi
exit 0
elif [ ${users} -eq 0 -a ${pty} -eq 0 -a ${tcp} -eq 0 -a ${load} -eq 0 -a ${zzz} -eq 1 ]
then
ltime=$(<${lastlog})
ltime=$(expr ${ltime} + ${overtime})
test ${ctime} -le ${ltime} && exit 2
echo "Power-off uptime=${uptime}/${timeup}s" | tee /dev/stderr | logger -t "auto-poweroff"
test -f ${lastlog} && rm ${lastlog}
test -f ${zzz} && rm ${zzz}
/sbin/poweroff
else
echo "Defer uptime=${uptime}/${timeup}s users=${users} pty=${pty} tcp=${tcp} loadavg=${loadavg}/${cpu} zzz=${zzz}" | tee /dev/stderr | logger -t "auto-poweroff"
echo ${ctime} > ${lastlog}
exit 2
fi
### END ###
シャットダウン条件を満たしたら、フラグを削除してシャットダウンを実行する。
昔に作った同じ目的のスクリプトを引っ張り出してきたのだが、Ubuntu 26.04で変わってしまった点を修正した。