こんにちはWorkaholicです。
今回はLinuxにてプログラムのプロセスをシェル(Bshell)で起動停止する実装方法について説明します。
よく業務でありがちな実装なので、初心者の方は参考ににしてみてください
・前提
常駐をするプログラムがある場合にはそれを起動停止する仕組が必要になります。
製品系であれば起動停止コマンドが用意されていますが、業務の都合上製品が使用できず、スクラッチ開発にて監視系ツールを常駐させるなどの実装を行う場合は往々にしてあります。しかしその場合には個別で起動停止が出来る仕組みも併せて開発をする必要性があります。
開発をするというレベルのモノではありませんが、実際に実装するとなると具体的にどのレベルで実装を行えばよいか?という事を聞かれる事が多々ありますので、私の経験上での実装方法を記載しておきます。
・模擬常駐プログラム
テスト用の常駐プログラムです。名前は「test.sh」とし、これの起動停止を行うシェルを実装します。
#!/bin/sh
while true
do
sleep 1
done
・起動shell
以下が起動シェルの中身です。
#/bin/sh
#test.sh
pro=`ps -ef | grep -v grep | grep "test.sh" | awk -F' ' '{print $2}'`
if [ -n "${pro}" ]; then
echo "既に起動しています。"
exit 0
fi
nohup /bin/sh ./test.sh >/dev/null 2>&1 &
pro=`ps -ef | grep -v grep | grep "test.sh" | awk -F' ' '{print $2}'`
if [ -n "${pro}" ]; then
echo "起動しました。"
else
echo "起動に失敗しました。"
exit 2
fi
exit 0
・解説
以下部分にて既にtest.shが起動していないか確認をしています。これが無いと多重起動してしまいます。
pro=`ps -ef | grep -v grep | grep "test.sh" | awk -F' ' '{print $2}'`
if [ -n "${pro}" ]; then
echo "既に起動しています。"
exit 0
fi
「ps -ef | grep “test.sh”」の結果に対して「grep -v grep 」でgrepで検索した際のプロセスを対象から除き、「awk -F’ ‘ ‘{print $2}’」でスペースで区切った2番目の列の値を取得します。※赤太字の場所(プロセスID)を取得しています。
# ps -ef | grep "test.sh"
root 22895 1 0 01:30 pts/0 00:00:00 /bin/sh ./test.sh
root 22910 931 0 01:30 pts/0 00:00:00 grep --color=auto test.sh
if文の条件として「-n」を指定します。変数「${pro}」が空でなければ条件に合致すると判定します。
プロセスIDが取得できなければ未起動状態、取得出来れば起動済と判定が出来ます。
if [ -n "${pro}" ]; then
echo "既に起動しています。"
exit 0
fi
「nohup」コマンドを使用して「test.sh」をバックグランドで実行します。
「>/dev/null 2>&1」を付けて出力を捨てておかないと以下図の表示が出るので注意
nohup /bin/sh ./test.sh >/dev/null 2>&1 &
再度プロセスIDの確認を行います。「test.sh」が正しく起動出来れいれば変数「${pro}」にプロセスIDが入りますので「起動しました。」と表示されます。空であれば「起動に失敗しました。」と表示され、「exit 2」として異常終了させます。
pro=`ps -ef | grep -v grep | grep "test.sh" | awk -F' ' '{print $2}'`
if [ -n "${pro}" ]; then
echo "起動しました。"
else
echo "起動に失敗しました。"
exit 2
fi
exit 0
・停止shell
以下が停止シェルの中身です。
#!/bin/sh
pro=`ps -ef | grep -v grep | grep "test.sh" | awk -F' ' '{print $2}'`
if [ -z "${pro}" ]; then
echo "既に停止しています。"
exit 0
fi
kill ${pro}
pro=`ps -ef | grep -v grep | grep "test.sh" | awk -F' ' '{print $2}'`
if [ -z "${pro}" ]; then
echo "停止しました。"
else
echo "停止に失敗しました。"
exit 2
fi
exit 0
・解説
基本的な考え方としては起動シェルの逆です。「-z」で変数「${pro}」が空であれば条件に合致すると判定します。
pro=`ps -ef | grep -v grep | grep "test.sh" | awk -F' ' '{print $2}'`
if [ -z "${pro}" ]; then
echo "既に停止しています。"
exit 0
fi
killコマンドに落としたいプロセスIDを引数に渡し、終了させます。
特にオプションはつけなくてもOKですが、重要度や性質によって異なる為都度判断してください
kill ${pro}
「@IT【 kill 】コマンド/【 killall 】コマンド――実行中のプロセスを終了させる」
※詳しいオプションは以下を参照
「kill」コマンド後に、プロセスが終了することが出来たか確認をします。
変数「${pro}」が空であれば「停止しました。」と表示され。空でなければまだプロセスは生きていますので「停止に失敗しました。」と表示されます。
pro=`ps -ef | grep -v grep | grep "test.sh" | awk -F' ' '{print $2}'`
if [ -z "${pro}" ]; then
echo "停止しました。"
else
echo "停止に失敗しました。"
exit 2
fi
exit 0
・最後に
シェルによる起動停止の一例を紹介しました。
新人SEが見ているかもしれないので一応言っておくと、実装方法は各現場によって異なる場合があります。
基本的には現場の実装方法に合わせて開発しましょう。ネットにあって動くからコピペしましたはレビューには通らないので注意です。使用するにしても何故これで大丈夫なのかを説明できるようにして使用するようにしてください
コメント