2017年7月11日火曜日

bash cronを止めるスクリプト

自サーバーで常時動いているapacheのプロセスは8つ。

それプラスその時々のapacheのプロセスが立ち上がったり終了したりしている。

で、最近あるプログラムが原因でうまく終了しないプロセスがたまにできてしまう。
それはkillしても消えない。
そうなるとOS自体の再起動になるのだが、一旦つまずいたのを気づかずに放っておくと、cronで起動しているものだからプロセスがどんどん増えていってしまう。

根本的な解決ができるまで、プロセスが増えてしまった時にメールで知らせるのと同時にそのcronを止めるスクリプト。

------------最終型  test.sh-----------------------
#!/bin/bash

#apacheのプロセス数
apanum=`grep -c 'apache' <(ps aux)`

#apacheのプロセス表示
apaer=`ps -u apache -f`

if [ $apanum -gt 100 ]; then

#echo 'more than 100'
mv /etc/cron.d/hoge /etc/con.d/.hoge
ps -u apache -f | mail -s ${apanum} Apache Process hoge@hoge.com

else
#echo 'less than or equal to 100'
#必要ならチェックしたことをログに残しておく。
:
fi

--------------------------------------

cronを止める仕組みは、
/etc/cron.d/hoge
というcronファイルhogeを.hogeと隠しファイルにすると動作が止まるので、その事を利用する。

で、次。
テストとしてapacehのプロセス数の確認で下のようにスクリプトを書いたら動かない
-----------------------
#!/bin/bash

if [ ps aux | grep -c 'apache' > 100 ]; then
echo 'more than 100'
else
echo 'less than 100'
fi

-------------------------
上の赤いところがダメなところだった。
で、こう直した。
------------------------
apanum=`grep -c 'apache' <(ps aux)`
if [ $apanum -gt 100 ]; then
echo 'more than 100'
else
echo 'less than 100'
fi
---------------------------

まず最初にシェルスクリプトでは、'<'とか、'>'を数値比較には使わないらしい。
A>B が A -gt B
A<B が A -lt B
となるそうだ。知らなかった。

あとは、パイプ(とリダクション)はパイプによって渡された後のコマンドが別のプロセスとして動くのでパイプ後のコマンドの結果をスクリプトで使うことはできないのだそうだ。(mailコマンドはパイプでつないでも動いた。)

上スクリプトのエラーとして
./hoge.sh: line 11: [: missing `]'
grep: ]: No such file or directory
が出た。
パイプが認識されていないならこういうエラーになるよなぁ。

この場合、プロセス置換(Process substitution)を使うか、一旦どこか一時ファイルに書き出してそれを読み込むしかないそうだ。
(プロセス置換も一時ファイルに書き出すことを裏(子プロセス)でやっているだけだから、やっていることは自分で書き出すのと一緒だそうだ。(実際、自分のCentOS6では/dev/fd/の下に一時ファイルが作られている。)

プロセス置換の書き方は、   
<(コマンドリスト)   コマンドの結果をファイルに加工されたもの。
>(コマンドリスト)   出力先をコマンドに渡す。

自分の場合、
<(ps aux)
としてps auxの結果をファイルとして出している。
)
(プロセス置換はbashでは動くがshでは動かないそうだ。)

*ここで「/bin/sh」と「/bin/bash」の違いの説明。
「/bin/sh」は「/bin/bash」へのシンボリックリンク。
でも「sh という名前で bash を起動すると、 bash は古くからある sh の起動動作をできるだけ真似しようとします。」ということだそうだ。




0 件のコメント:

コメントを投稿