私はスクリプトの下で実行しています:
#!/bin/bash
ps ax | grep -q [v]arnish
if [ $? -eq 0 ];then
echo varnish is running...
exit 0
else
echo "Critical : varnish is not running "
exit 2
fi
出力は::
[root@server ~]# sh -x check_varnish_pro.sh
+ ps ax
+ grep -q '[v]arnish'
+ '[' 0 -eq 0 ']'
+ echo varnish is running...
varnish is running...
+ exit 0
コマンドラインで同じように実行すると、終了ステータスが1になります。
[root@server ~]# ps ax | grep -q [v]arnish; echo $?
1
ワニスがサーバーにインストールされていないような場合です。このスクリプトは、ワニスがインストールされているサーバーで正常に動作します。
スクリプトとコマンドラインを使用して実行すると、終了ステータスが異なるのはなぜですか?このスクリプトを改善するには?
check_varnish_pro.sh
という名前のスクリプトを実行すると、テスト
ps ax | grep -q [v]arnish
check_
varnish_pro
という名前のスクリプトが実行されているため、成功します。
一般に、ps
とgrep
を使用して単純なアプローチを試し、特定のプロセスが実行されているかどうかを確認することはお勧めできません。
これにはpgrep
を使用する方がはるかに良いでしょう。
if pgrep "varnish" >/dev/null; then
echo "Varnish in running"
else
echo "Varnish is not running"
fi
pgrep
のマニュアルを参照してください。一部のシステム(おそらくLinuxではない)では、grep
の同じフラグに対応する-q
フラグを取得します。これにより、/dev/null
にリダイレクトする必要がなくなります。また、プロセス名だけではなく、コマンドライン全体で一致を実行する-f
フラグもあります。 -u
を使用して、特定のユーザーに属するプロセスに一致を制限することもできます。
pgrep
をインストールすると、pkill
にもアクセスできるようになり、名前に基づいてプロセスに信号を送ることができます。
また、これがサービスデーモンの場合であり、UNIXシステムに情報(たとえば、稼働しているかどうか)を照会する方法がある場合、それはproperそれをチェックする方法。
Linuxではsystemctl
(systemctl is-active --quiet varnish
は実行中は0を返し、それ以外は3を返します)、OpenBSDではrcctl
などになります。
今あなたのスクリプトに:
スクリプトでは、ps ax
からの出力を解析します。この出力には、スクリプト自体の名前check_varnish_pro.sh
が含まれ、これには明らかに文字列varnish
が含まれます。これにより、誤検知が発生します。テスト中にgrep
の-q
フラグなしで実行した場合、これを見つけたでしょう。
#!/bin/bash
ps ax | grep '[v]arnish'
それを実行する:
$ ./check_varnish_pro.sh
31004 p1 SN+ 0:00.04 /bin/bash ./check_varnish_pro.sh
もう1つの問題は、パターンで[v]
を使用して、grep
プロセスがgrep
自体によって検出されないようにしようとした場合です。 varnish
という名前のファイルまたはディレクトリが含まれているディレクトリでスクリプトまたはコマンドラインを実行すると、このアプローチは失敗します(この場合、再び誤検知が発生します)。これは、パターンが引用符で囲まれておらず、シェルがそれを使用してファイル名の展開を実行するためです。
見る:
bash-4.4$ set -x
bash-4.4$ ps ax | grep [v]arnish
+ ps ax
+ grep '[v]arnish'
bash-4.4$ touch varnish
+ touch varnish
bash-4.4$ ps ax | grep [v]arnish
+ ps ax
+ grep varnish
91829 p2 SN+p 0:00.02 grep varnish
ファイルvarnish
が存在すると、シェルは[v]arnish
をファイル名varnish
に置き換え、プロセステーブルのパターン(grep
処理する)。
@ AlexPは説明します 実際に何が起こっているのかを非常に簡潔に説明していますが、重要なプロセスにpgrep
/pkill
を使用するの@Kusalanandaの考えは 強く非推奨 。より良い解決策は次のとおりです。
systemctl status varnishd
は、最新の* nixインストールでそれを処理する必要があります。不幸な状況でサービスを利用できない場合は、起動スクリプトを変更して、プロセスが終了したらすぐに問題を報告できます。
varnish || true
some_command_to_send_an_alert_that_the_service_has_died
kill -0 "$pid"
を使用して定期的に状態を確認します。