サーバ稼働時間をHTML上に表示する(力技)

このサイトは非常にポンコツな自宅サーバで動いているんですが、なんとなく自分のサーバのuptimeを見てみたら、200日を超えていました。すぐ壊れるだろうと思っていたのに、案外元気に動いてくれているようです。
サイトのトップにサーバの連続稼働時間を表示してやろうという気持ちが湧いてきて調べたところ、どうやらPHPかPerlで書くのが普通らしい→さっぱり分からない
そこで、シェルスクリプトのゴリ押しだけでやってやろうと思い立ちました。ついでに最長記録を保存する機能も付けようかと。

uptimeコマンドの実行結果を次の例とします。
# uptime
01:12:34 up 28 min, 1 users, load average: 0.00, 0.00, 0.15 #1時間未満のとき
02:34:56 up 2:25, 1 users, load average: 0.00, 0.15, 0.05 #1時間以上1日未満のとき
03:45:55 up 23 days, 4:35, 1 users, load average: 0.15, 0.05, 0.00 #1日以上のとき

何で書式が3種類もあるんだよ!嫌がらせか!

シェルスクリプトを、
/hoge/hage/uptime.sh /hogehoge/hoge.html
のように実行します。


#!/bin/bash


#--サーバ連続稼働時間と過去の最長稼働時間をhtml上に表示するシェルスクリプト uptime.sh--

#----------------------------------------------------------------------------------------------------------------------------------------------------

#01:12:34 up 28 min,  1 users,  load average: 0.00, 0.00, 0.15	…1時間未満のとき
#02:34:56 up  2:25,  1 users,  load average: 0.00, 0.15, 0.05	…1時間以上1日未満のとき
#03:45:55 up 23 days,  4:35,  1 users,  load average: 0.15, 0.05, 0.00	…1日以上のとき
#上記をuptime実行結果の例とします.

#cronを使って,/hoge/hoge/uptime.sh /hogehoge/hoge.html のように定期的に実行すると,hoge.html中の
#<!-- uptime --><!-- uptime_end -->で囲まれた部分にサーバ連続稼働時間,
#<!-- uptime_MAX --><!-- uptime_MAX_end -->で囲まれた部分に過去の最長連続稼働時間を表示します.

#このスクリプトは,同じディレクトリ内に"uptime_MAX.txt"を自動生成します.

#----------------------------------------------------------------------------------------------------------------------------------------------------


echo 0 0 0 >>uptime_MAX.txt	#uptime_MAX.txtが存在しなければ作成して0 0 0を記入,あれば0 0 0を末尾に追記
CHK=`uptime | awk '{print $4}'`	#uptime実行結果の第4パラメータを変数CHKに代入 結果:CHK=[min,], [days,] or others

case "$CHK" in

	"days," )	#変数CHK=days,のとき
		DAY=`uptime | awk '{print $3}'`	#uptime実行結果の第3パラメータを変数DAYに代入
		HOUR=`uptime | awk '{print $5}' | sed -e 's/\(.*\):.*/\1/'`	#uptime実行結果の第5パラメータのうち,00:00のような部分の:より前を変数HOURに代入
		MINUTE=`uptime | awk '{print $5}' | sed -e 's/.*:\(.*\),.*/\1/'`	#uptime実行結果の第5パラメータのうち,00:00のような部分の:より後を変数MINUTEに代入
		COUNT_SUM=`expr ${DAY} \* 1440 + ${HOUR} \* 60 + ${MINUTE}`	#uptimeを分に換算して変数COUNT_SUMに代入

		DAY_MAX=`head -n 1 uptime_MAX.txt | awk '{print $1}'`	#uptime_MAX.txtの第1行を取得し,第1パラメータを変数DAY_MAXに代入
		HOUR_MAX=`head -n 1 uptime_MAX.txt | awk '{print $2}'`	#uptime_MAX.txtの第1行を取得し,第2パラメータを変数HOUR_MAXに代入
		MINUTE_MAX=`head -n 1 uptime_MAX.txt | awk '{print $3}'`	#uptime_MAX.txtの第1行を取得し,第3パラメータを変数MINUTE_MAXに代入
		COUNT_MAX=${DAY_MAX}" "${HOUR_MAX}" "${MINUTE_MAX}	#変数DAY,HOUR,MINUTEをスペース区切りにして変数COUNT_MAXに代入
		echo $COUNT_MAX >uptime_MAX.txt	#uptime_MAX.txtの内容を変数COUNT_MAXの内容で上書き
		COUNT_MAX_SUM=`expr ${DAY_MAX} \* 1440 + ${HOUR_MAX} \* 60 + ${MINUTE_MAX}`	#uptime_MAXを分に換算して変数COUNT_MAX_SUMに代入

			if test ${COUNT_SUM} -ge ${COUNT_MAX_SUM}	#最長記録の更新を確認
			then
				COUNT_MAX=${DAY}" "${HOUR}" "${MINUTE}	#変数DAY,HOUR,MINUTEをスペース区切りにして変数COUNT_MAXに代入
				echo $COUNT_MAX >uptime_MAX.txt	#uptime_MAX.txtの内容を変数COUNT_MAXの内容で上書き

				DAY_MAX=`head -n 1 uptime_MAX.txt | awk '{print $1}'`	#uptime_MAX.txtの第1行を取得し,第1パラメータを変数DAY_MAXに代入
				HOUR_MAX=`head -n 1 uptime_MAX.txt | awk '{print $2}'`	#uptime_MAX.txtの第1行を取得し,第2パラメータを変数HOUR_MAXに代入
				MINUTE_MAX=`head -n 1 uptime_MAX.txt | awk '{print $3}'`	#uptime_MAX.txtの第1行を取得し,第3パラメータを変数MINUTE_MAXに代入
			fi

		sed -e "s/<\!-. uptime .->..*<\!-. uptime_end .->/<\!-- uptime -->${DAY}d ${HOUR}h ${MINUTE}m<\!-- uptime_end -->/" $1 > $1.tmp 
		#スクリプト実行時に渡された第1パラメータ(/hogehoge/hoge.html)中の<!-- uptime --><!-- uptime_end -->で囲まれた範囲の中を書き換えたものをhoge.html.tmpに出力
		rm -rf $1	#hoge.htmlを消去
		mv $1.tmp $1	#hoge.html.tmpをhoge.htmlにリネーム

		sed -e "s/<\!-. uptime_MAX .->..*<\!-. uptime_MAX_end .->/<\!-- uptime_MAX -->${DAY_MAX}d ${HOUR_MAX}h ${MINUTE_MAX}m<\!-- uptime_MAX_end -->/" $1 > $1.tmp 
				#スクリプト実行時に渡された第1パラメータ(/hogehoge/hoge.html)中の<!-- uptime_MAX --><!-- uptime_MAX_end -->で囲まれた範囲を書き換えたものをhoge.html.tmpに出力
		rm -rf $1	#hoge.htmlを消去
		mv $1.tmp $1	#hoge.html.tmpをhoge.htmlにリネーム
	;;

	"min," )	#変数CHK=min,のとき
		DAY=0	#変数DAYに0を代入
		HOUR=0	#変数HOURに0を代入
		MINUTE=`uptime | awk '{print $3}'`	#uptime実行結果の第3パラメータを変数MINUTEに代入
		COUNT_SUM=`expr ${DAY} \* 1440 + ${HOUR} \* 60 + ${MINUTE}`	#uptimeを分に換算して変数COUNT_SUMに代入

		DAY_MAX=`head -n 1 uptime_MAX.txt | awk '{print $1}'`	#uptime_MAX.txtの第1行を取得し,第1パラメータを変数DAY_MAXに代入
		HOUR_MAX=`head -n 1 uptime_MAX.txt | awk '{print $2}'`	#uptime_MAX.txtの第1行を取得し,第2パラメータを変数HOUR_MAXに代入
		MINUTE_MAX=`head -n 1 uptime_MAX.txt | awk '{print $3}'`	#uptime_MAX.txtの第1行を取得し,第3パラメータを変数MINUTE_MAXに代入
		COUNT_MAX=${DAY_MAX}" "${HOUR_MAX}" "${MINUTE_MAX}	#変数DAY,HOUR,MINUTEをスペース区切りにして変数COUNT_MAXに代入
		echo $COUNT_MAX >uptime_MAX.txt	#uptime_MAX.txtの内容を変数COUNT_MAXの内容で上書き
		COUNT_MAX_SUM=`expr ${DAY_MAX} \* 1440 + ${HOUR_MAX} \* 60 + ${MINUTE_MAX}`	#uptime_MAXを分に換算して変数COUNT_MAX_SUMに代入

			if test ${COUNT_SUM} -ge ${COUNT_MAX_SUM}	#最長記録の更新を確認
			then
				COUNT_MAX=${DAY}" "${HOUR}" "${MINUTE}	#変数DAY,HOUR,MINUTEをスペース区切りにして変数COUNT_MAXに代入
				echo $COUNT_MAX >uptime_MAX.txt	#uptime_MAX.txtの内容を変数COUNT_MAXの内容で上書き

				DAY_MAX=`head -n 1 uptime_MAX.txt | awk '{print $1}'`	#uptime_MAX.txtの第1行を取得し,第1パラメータを変数DAY_MAXに代入
				HOUR_MAX=`head -n 1 uptime_MAX.txt | awk '{print $2}'`	#uptime_MAX.txtの第1行を取得し,第2パラメータを変数HOUR_MAXに代入
				MINUTE_MAX=`head -n 1 uptime_MAX.txt | awk '{print $3}'`	#uptime_MAX.txtの第1行を取得し,第3パラメータを変数MINUTE_MAXに代入
			fi

		sed -e "s/<\!-. uptime .->..*<\!-. uptime_end .->/<\!-- uptime -->${DAY}d ${HOUR}h ${MINUTE}m<\!-- uptime_end -->/" $1 > $1.tmp 
		#スクリプト実行時に渡された第1パラメータ(/hogehoge/hoge.html)中の<!-- uptime --><!-- uptime_end -->で囲まれた範囲の中を書き換えたものをhoge.html.tmpに出力
		rm -rf $1	#hoge.htmlを消去
		mv $1.tmp $1	#hoge.html.tmpをhoge.htmlにリネーム

		sed -e "s/<\!-. uptime_MAX .->..*<\!-. uptime_MAX_end .->/<\!-- uptime_MAX -->${DAY_MAX}d ${HOUR_MAX}h ${MINUTE_MAX}m<\!-- uptime_MAX_end -->/" $1 > $1.tmp 
				#スクリプト実行時に渡された第1パラメータ(/hogehoge/hoge.html)中の<!-- uptime_MAX --><!-- uptime_MAX_end -->で囲まれた範囲を書き換えたものをhoge.html.tmpに出力
		rm -rf $1	#hoge.htmlを消去
		mv $1.tmp $1	#hoge.html.tmpをhoge.htmlにリネーム
	;;

	* )	#変数CHKが上2つに当てはまらないとき
		DAY=0	#変数DAYに0を代入
		HOUR=`uptime | awk '{print $3}' | sed -e 's/\(.*[^,]\):.*/\1/'`	#uptime実行結果の第3パラメータのうち,00:00のような部分の:より前を変数HOURに代入(,は除去する)
		MINUTE=`uptime | awk '{print $3}' | sed -e 's/.*:\(.*[^,]\),.*/\1/'`	#uptime実行結果の第3パラメータのうち,00:00のような部分の:より後を変数MINUTEに代入(,は除去する)
		COUNT_SUM=`expr ${DAY} \* 1440 + ${HOUR} \* 60 + ${MINUTE}`	#uptimeを分に換算して変数COUNT_SUMに代入

		DAY_MAX=`head -n 1 uptime_MAX.txt | awk '{print $1}'`	#uptime_MAX.txtの第1行を取得し,第1パラメータを変数DAY_MAXに代入
		HOUR_MAX=`head -n 1 uptime_MAX.txt | awk '{print $2}'`	#uptime_MAX.txtの第1行を取得し,第2パラメータを変数HOUR_MAXに代入
		MINUTE_MAX=`head -n 1 uptime_MAX.txt | awk '{print $3}'`	#uptime_MAX.txtの第1行を取得し,第3パラメータを変数MINUTE_MAXに代入
		COUNT_MAX=${DAY_MAX}" "${HOUR_MAX}" "${MINUTE_MAX}	#変数DAY,HOUR,MINUTEをスペース区切りにして変数COUNT_MAXに代入
		echo $COUNT_MAX >uptime_MAX.txt	#uptime_MAX.txtの内容を変数COUNT_MAXの内容で上書き
		COUNT_MAX_SUM=`expr ${DAY_MAX} \* 1440 + ${HOUR_MAX} \* 60 + ${MINUTE_MAX}`	#uptime_MAXを分に換算して変数COUNT_MAX_SUMに代入

			if test ${COUNT_SUM} -ge ${COUNT_MAX_SUM}	#最長記録の更新を確認
			then
				COUNT_MAX=${DAY}" "${HOUR}" "${MINUTE}	#変数DAY,HOUR,MINUTEをスペース区切りにして変数COUNT_MAXに代入
				echo $COUNT_MAX >uptime_MAX.txt	#uptime_MAX.txtの内容を変数COUNT_MAXの内容で上書き

				DAY_MAX=`head -n 1 uptime_MAX.txt | awk '{print $1}'`	#uptime_MAX.txtの第1行を取得し,第1パラメータを変数DAY_MAXに代入
				HOUR_MAX=`head -n 1 uptime_MAX.txt | awk '{print $2}'`	#uptime_MAX.txtの第1行を取得し,第2パラメータを変数HOUR_MAXに代入
				MINUTE_MAX=`head -n 1 uptime_MAX.txt | awk '{print $3}'`	#uptime_MAX.txtの第1行を取得し,第3パラメータを変数MINUTE_MAXに代入
			fi

		sed -e "s/<\!-. uptime .->..*<\!-. uptime_end .->/<\!-- uptime -->${DAY}d ${HOUR}h ${MINUTE}m<\!-- uptime_end -->/" $1 > $1.tmp 
		#スクリプト実行時に渡された第1パラメータ(/hogehoge/hoge.html)中の<!-- uptime --><!-- uptime_end -->で囲まれた範囲の中を書き換えたものをhoge.html.tmpに出力
		rm -rf $1	#hoge.htmlを消去
		mv $1.tmp $1	#hoge.html.tmpをhoge.htmlにリネーム

		sed -e "s/<\!-. uptime_MAX .->..*<\!-. uptime_MAX_end .->/<\!-- uptime_MAX -->${DAY_MAX}d ${HOUR_MAX}h ${MINUTE_MAX}m<\!-- uptime_MAX_end -->/" $1 > $1.tmp 
				#スクリプト実行時に渡された第1パラメータ(/hogehoge/hoge.html)中の<!-- uptime_MAX --><!-- uptime_MAX_end -->で囲まれた範囲を書き換えたものをhoge.html.tmpに出力
		rm -rf $1	#hoge.htmlを消去
		mv $1.tmp $1	#hoge.html.tmpをhoge.htmlにリネーム
	;;

esac

意外と1日で書けました。何かしらバグがありそうだけど

uptime.sh

やっぱりダメでした。まずuptime_MAX.txtを相対パスにしていたため、手打ちでは動いてもcronでは動きませんでした。
絶対パスを自動で取得しようとしたところ、うちのポンコツにはdirnameが無かったので(組み込みLinuxなので追加できない)手動の設定項目にしました。
そして修正後、しばらく動かしているとなんか変な値が…
実は、uptimeの書式は4種類ありました。ウゼエ!
そこを修正した後、改めて全体を眺めてみると…なんか異常に冗長じゃないかコレ?
結局case文を使ったせいで余計面倒なことになっていたので、if文に直したところスッキリしました。


#!/bin/sh


#--サーバ連続稼働時間と過去の最長稼働時間をhtml上に表示するシェルスクリプト uptime.sh-- 2015.03.14 <http://5400rpm.myhome.cx/>

#----------------------------------------------------------------------------------------------------------------------------------------------------

#01:12:34 up 28 min,  1 users,  load average: 0.00, 0.00, 0.15	…1時間未満のとき
#02:34:56 up  2:25,  1 users,  load average: 0.00, 0.15, 0.05	…1時間以上1日未満のとき
#03:15:51 up 23 days,  3 min,  1 users,  load average: 0.15, 0.05, 0.00	…1日+1時間未満以上のとき
#03:45:55 up 23 days,  4:35,  1 users,  load average: 0.15, 0.05, 0.00	…1日+1時間以上のとき
#上記をuptime実行結果の例とします.

#cronを使って,/hoge/hoge/uptime.sh /hogehoge/hoge.html のように定期的に実行すると,hoge.html中の
<!-- uptime --><!-- uptime_end -->で囲まれた部分にサーバ連続稼働時間,
#<!-- uptime_MAX --><!-- uptime_MAX_end -->で囲まれた部分に過去の最長連続稼働時間を表示します.

#このスクリプトは,指定ディレクトリ内に"uptime_MAX.txt"を自動生成します.

#----------------------------------------------------------------------------------------------------------------------------------------------------

################################################################

FILE=/usr/uptime/uptime_MAX.txt	#環境に合わせて設定してください

################################################################

echo 0 0 0 >>${FILE}	#uptime_MAX.txtが存在しなければ作成して0 0 0を記入,あれば0 0 0を末尾に追記
CHK=`uptime | awk '{print $4}'`	#uptime実行結果の第4パラメータを変数CHKに代入 結果:CHK=[min,], [days,] or others

	if test ${CHK} = "days,"	#変数CHK=days,のとき
	then
		CHK=`uptime | awk '{print $6}'`	#uptime実行結果の第6パラメータを変数CHKに代入 結果:CHK=[min,] or others

			if test ${CHK} = "min,"	#変数CHK=min,のとき
			then
				DAY=`uptime | awk '{print $3}'`	#uptime実行結果の第3パラメータを変数DAYに代入
				HOUR=0	#変数HOURに0を代入
				MINUTE=`uptime | awk '{print $5}' | sed -e 's/.*:\(.*[^,]\),.*/\1/'`	#uptime実行結果の第5パラメータのうち,00:00のような部分の:より後を変数MINUTEに代入(,は除去する)
			else
				DAY=`uptime | awk '{print $3}'`	#uptime実行結果の第3パラメータを変数DAYに代入
				HOUR=`uptime | awk '{print $5}' | sed -e 's/\(.*\):.*/\1/'`	#uptime実行結果の第5パラメータのうち,00:00のような部分の:より前を変数HOURに代入
				MINUTE=`uptime | awk '{print $5}' | sed -e 's/.*:\(.*\),.*/\1/'`	#uptime実行結果の第5パラメータのうち,00:00のような部分の:より後を変数MINUTEに代入
			fi

	elif test ${CHK} = "min,"	#変数CHK=min,のとき
	then

		DAY=0	#変数DAYに0を代入
		HOUR=0	#変数HOURに0を代入
		MINUTE=`uptime | awk '{print $3}'`	#uptime実行結果の第3パラメータを変数MINUTEに代入

	else

		DAY=0	#変数DAYに0を代入
		HOUR=`uptime | awk '{print $3}' | sed -e 's/\(.*[^,]\):.*/\1/'`	#uptime実行結果の第3パラメータのうち,00:00のような部分の:より前を変数HOURに代入(,は除去する)
		MINUTE=`uptime | awk '{print $3}' | sed -e 's/.*:\(.*[^,]\),.*/\1/'`	#uptime実行結果の第3パラメータのうち,00:00のような部分の:より後を変数MINUTEに代入(,は除去する)

	fi

COUNT_SUM=`expr ${DAY} \* 1440 + ${HOUR} \* 60 + ${MINUTE}`	#uptimeを分に換算して変数COUNT_SUMに代入

DAY_MAX=`head -n 1 ${FILE} | awk '{print $1}'`	#uptime_MAX.txtの第1行を取得し,第1パラメータを変数DAY_MAXに代入
HOUR_MAX=`head -n 1 ${FILE} | awk '{print $2}'`	#uptime_MAX.txtの第1行を取得し,第2パラメータを変数HOUR_MAXに代入
MINUTE_MAX=`head -n 1 ${FILE} | awk '{print $3}'`	#uptime_MAX.txtの第1行を取得し,第3パラメータを変数MINUTE_MAXに代入

COUNT_MAX=${DAY_MAX}" "${HOUR_MAX}" "${MINUTE_MAX}	#変数DAY_MAX,HOUR_MAX,MINUTE_MAXをスペース区切りにして変数COUNT_MAXに代入
COUNT_MAX_SUM=`expr ${DAY_MAX} \* 1440 + ${HOUR_MAX} \* 60 + ${MINUTE_MAX}`	#uptime_MAXを分に換算して変数COUNT_MAX_SUMに代入

	if test ${COUNT_SUM} -ge ${COUNT_MAX_SUM}	#最長記録の更新を確認
	then
		COUNT_MAX=${DAY}" "${HOUR}" "${MINUTE}	#変数DAY,HOUR,MINUTEをスペース区切りにして変数COUNT_MAXに代入
		echo $COUNT_MAX >${FILE}	#uptime_MAX.txtの内容を変数COUNT_MAXの内容で上書き

		DAY_MAX=`head -n 1 ${FILE} | awk '{print $1}'`	#uptime_MAX.txtの第1行を取得し,第1パラメータを変数DAY_MAXに代入
		HOUR_MAX=`head -n 1 ${FILE} | awk '{print $2}'`	#uptime_MAX.txtの第1行を取得し,第2パラメータを変数HOUR_MAXに代入
		MINUTE_MAX=`head -n 1 ${FILE} | awk '{print $3}'`	#uptime_MAX.txtの第1行を取得し,第3パラメータを変数MINUTE_MAXに代入

	else
		echo $COUNT_MAX >${FILE}	#uptime_MAX.txtの内容を変数COUNT_MAXの内容で上書き(uptime_MAX.txtに無限に0 0 0が追記されるのを防ぐ)

	fi

sed -e "s/<\!-. uptime .->..*<\!-. uptime_end .->/<\!-- uptime -->${DAY}d ${HOUR}h ${MINUTE}m<\!-- uptime_end -->/" $1 > $1.tmp
#スクリプト実行時に渡された第1パラメータ(/hogehoge/hoge.html)中の<!-- uptime --><!-- uptime_end -->で囲まれた範囲の中を書き換えたものをhoge.html.tmpに出力
rm -rf $1	#hoge.htmlを消去
mv $1.tmp $1	#hoge.html.tmpをhoge.htmlにリネーム

sed -e "s/<\!-. uptime_MAX .->..*<\!-. uptime_MAX_end .->/<\!-- uptime_MAX -->${DAY_MAX}d ${HOUR_MAX}h ${MINUTE_MAX}m<\!-- uptime_MAX_end -->/" $1 > $1.tmp
#スクリプト実行時に渡された第1パラメータ(/hogehoge/hoge.html)中の<!-- uptime_MAX --><!-- uptime_MAX_end -->で囲まれた範囲を書き換えたものをhoge.html.tmpに出力
rm -rf $1	#hoge.htmlを消去
mv $1.tmp $1	#hoge.html.tmpをhoge.htmlにリネーム

uptime.sh