30代半ばの事務職員がITエンジニアになった話

おおよそタイトルのとおり、30代半ばにしてITエンジニアのタマゴになってしまった会社員の話

【Linux】シェルスクリプトを書いてみる 死活監視の延長でPingが死んでたらサービスを止めてみよう

シェルスクリプトを覚えたい、と
常々思ってはいたものの、
これをこうしたい!という具体的な
目的がないとなかなかすすまない
というのはよくあるパターンと思う


そこで、今回のお題
シェルを組んでサービスを自動的に止めたい
みたいな目標があると
覚えるいい機会になるなと


Pingが死んでたらサービスを強制的に止めるシェルスクリプト

どいういうことかと言うと


前回のブログに書いた通り
とあるサーバーが別のサーバーに
データを常に取りにいってて
通信断にでもなったら
エラーが蓄積されて最後は
ハングアウトするという
わけのわからない仕様


なので通信断となったら
通信しているサービスを止めよう
という発想
まぁだいぶレアケースだろうけど
こういうのをシェルスクリプト
対処しようと創作意欲がわく
、ということで


コード

#!/bin/sh

status1=`curl -I http://localhost/ping | grep HTTP`
status2=`echo $status1 | grep HTTP`
if [ "`echo $status2 | grep 200`" ]; then result1=1; else result1=0; fi
echo $status2

sleep 3s

status1=`curl -I http://localhost/ping | grep HTTP`
status2=`echo $status1 | grep HTTP`
if [ "`echo $status2 | grep 200`" ]; then result2=1; else result2=0; fi
echo $status2

sleep 3s

status1=`curl -I http://localhost/ping | grep HTTP`
status2=`echo $status1 | grep HTTP`
if [ "`echo $status2 | grep 200`" ]; then result3=1; else result3=0; fi
echo $status2

active=`ps -ef | grep ○○○ | grep -v grep | wc -l`

echo "ping1=" $result1
echo "ping2=" $result2
echo "ping3=" $result3
echo "activate=" $active

if [ $result1 -eq 1 ] && [ $result2 -eq 1 ] && [ $result3 -eq 1 ] && [ $active -eq 0 ];
then sudo service ○○○ start && echo tomcat started; fi

if [ $result1 -eq 0 ] && [ $result2 -eq 0 ] && [ $result3 -eq 0 ] && [ $active -eq 1 ];
then sudo service ○○○ stop && echo tomcat stoped; fi

 

解説


1行目に書く決まりごと
shとかbashとか他にもいろいろあるらしいけど
実はよくわかってない

#!/bin/sh


通信断となっているかをPingで確認
せっかくなので前回作成した
Javaのプログラムをデプロイして
…/ping/ でアクセスできるようにし
curl の結果を返すようにしている


curl の結果のHTTPの文字が入っている行を
抜きだしてるわけだけど
ふつうにPingコマンドにすることも可


JavaのプログラムでPingの対象のIPを
別ファイルにしておりIPの変更があった場合
そちらを変更するだけでいいように
このような仕様にしている次第

status1=`curl -I http://localhost/ping/ | grep HTTP`


curl の結果を抜き出したHTTPの行には
httpステータスのコードが入っている
200(通信OK)なら結果フラグを1にする

status2=`echo $status1 | grep HTTP`
if [ "`echo $status2 | grep 200`" ]; then result1=1; else result1=0; fi
echo $status2


Pingを3回打って結果をトリガーにする
仕様にしてみた
だけど立て続けにするとよくないようで
少し間を空けるとうまくいった

sleep 3s


ps -ef で実行中のプロセスを表示
grep で該当のサービスを抜き出す
そのままだと"grep"自身も
プロセスのひとつとして表示されて
しまうので grep -v grep
"grep"を除外する
wc -l で結果の行の数を出力


⇒こうすると変数"active"に
該当のサービスが起動していなければ0
起動していれば1以上が入るようになる

active=`ps -ef | grep ○○○ | grep -v grep | wc -l`


Pingの結果が3回ともOKかつ
サービスが起動していない状態なら
サービスを起動する

if [ $result1 -eq 1 ] && [ $result2 -eq 1 ] && [ $result3 -eq 1 ] && [ $active -eq 0 ];
then sudo service ○○○ start && echo tomcat started; fi


Pingの結果が3回ともNGかつ
サービスが起動していれば
サービスを停止する

if [ $result1 -eq 0 ] && [ $result2 -eq 0 ] && [ $result3 -eq 0 ] && [ $active -eq 1 ];
then sudo service ○○○ stop && echo tomcat stoped; fi