ユーザ用ツール

サイト用ツール


自動シャットダウン_スクリプト

自動シャットダウン スクリプト

Ubuntu Server 26.04は実験環境であるので、常時起動しておく必要はない。
作業完了時に自分でシャットダウンしてもよいが、切り忘れ対策として自動シャットダウンを仕込むことにした。

シャットダウン条件

システムの稼働時間が一定以上になり、かつ以下の条件で「無人・無負荷状態」が継続した場合に、自動でシャットダウンを実行する。

  • ログインユーザが存在しない
  • PTY が存在しない
  • TCP ESTABLISHED が存在しない
  • CPU load が 0

ただ、上記の条件だと日次で実行してほしい処理が、全く実行されないまま停止してしまう可能性がある。
そこで日次処理を行うanacronの処理が済んだあとに実行する条件を追加した。

  • anacronの日次処理の最後にフラグとなるファイルを作成するスクリプトを実行させる

日次処理実行済みのフラグ作成はanacronの処理の最後になるよう、アルファベットのzが連続するファイル名でスクリプトを作成する。

スクリプト

日次処理済のフラグを作成するスクリプト

/etc/cron.daily/zzz
#!/bin/sh
zzz=/var/local/zzz
touch ${zzz}

自動シャットダウンのスクリプトをcronで任意の間隔(10-60分)で実行する。

cron設定の例

/etc/cron.d/auto-poweroff
1,11,21,31,41,51 * * * * root /usr/local/sbin/auto-poweroff.sh 1>/dev/null 2>/dev/null

自動シャットダウン スクリプト

/usr/local/sbin/auto-poweroff.sh
#!/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コマンドに変更
自動シャットダウン_スクリプト.txt · 最終更新: by Minoru Kijima