====== 自動シャットダウン スクリプト ====== Ubuntu Server 26.04は実験環境であるので、常時起動しておく必要はない。\\ 作業完了時に自分でシャットダウンしてもよいが、切り忘れ対策として自動シャットダウンを仕込むことにした。 ===== シャットダウン条件 ===== システムの稼働時間が一定以上になり、かつ以下の条件で「無人・無負荷状態」が継続した場合に、自動でシャットダウンを実行する。 * ログインユーザが存在しない * PTY が存在しない * TCP ESTABLISHED が存在しない * CPU load が 0 ただ、上記の条件だと日次で実行してほしい処理が、全く実行されないまま停止してしまう可能性がある。\\ そこで日次処理を行うanacronの処理が済んだあとに実行する条件を追加した。 * 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 のための改修 ==== 昔に作った同じ目的のスクリプトを引っ張り出してきたのだが、Ubuntu 26.04で変わってしまった点を修正した。 * TCP接続のカウントをnetstatコマンドから/proc/net/tcpの参照に変更 * ローカルのログインのカウントをwhoコマンドからloginctlコマンドに変更