次のスクリプトを実行しています。
#!/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
この状況は、サーバーにニスがインストールされていないのと同じです。このスクリプトは、Varnish がインストールされているサーバーで正しく実行されます。
スクリプトとコマンドラインを使用して実行するときにシャットダウンステータスが異なるのはなぜですか?このスクリプトをどのように改善できますか?
答え1
一般に、特定のプロセスが実行されていることを確認するための簡単な方法を使用することはps
お勧めできませんgrep
。
pgrep
次の方法を使用することをお勧めします。
if pgrep "varnish" >/dev/null; then
echo "Varnish in running"
else
echo "Varnish is not running"
fi
マニュアルを参照してくださいpgrep
。一部のシステム(Linuxではない可能性があります)では、-q
同じフラグに対応するフラグを取得するため、grep
にリダイレクトする必要はありません。プロセス名だけでなく、コマンドライン全体で一致を実行するフラグ/dev/null
もあります。-f
使用されている特定のユーザーに属するプロセスの一致を制限することもできます-u
。
インストール後もpgrep
アクセスできるため、pkill
名前に基づいてプロセスにシグナルを送信できます。
返品、サービスデーモンの場合、Unixシステムにこれに関する情報(実行中かどうか)を照会する方法がある場合は、次のようにします。適切確認する方法。
Linuxではsystemctl
(systemctl is-active --quiet varnish
実行している場合は0を返し、そうでない場合は3を返します)OpenBSDではrcctl
などがあります。
今スクリプトとして:
スクリプトから出力を解析しますps ax
。この出力には、check_varnish_pro.sh
明らかに文字列を含むスクリプト自体の名前が含まれていますvarnish
。これはあなたに偽の肯定を与えるでしょう。テスト中にフラグなしで実行すると、-q
これがわかります。grep
#!/bin/bash
ps ax | grep '[v]arnish'
実行してください:
$ ./check_varnish_pro.sh
31004 p1 SN+ 0:00.04 /bin/bash ./check_varnish_pro.sh
grep
もう一つの問題は、プロセスをパターンとして使用して、それ自体が検出されないように「隠そうとする」ことです。指定されたファイルまたはディレクトリを含むディレクトリでスクリプトまたはコマンドラインを実行すると、この方法は失敗します。この場合、偽の肯定が発生します。これは、パターンが引用されず、シェルでファイル名のグロービングを実行するために使用されるためです。grep
[v]
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
。
答え2
check_varnish_pro.sh
testというスクリプトを実行すると
ps ax | grep -q [v]arnish
成功という名前の人がいるからだcheck_
塗料_pro
ランニング。
答え3
@AlexPが説明しました。実際に起こったことを非常に簡潔に説明していますが、@Kusalanandaの考えは次のとおりです。主なプロセスにpgrep
/を使用することは次のとおりです。pkill
とても落胆。より良い解決策は次のとおりです。
- 尋ねる提供する実行中です。
systemctl status varnishd
この問題は、最新の*nixインストールで修正する必要があります。 不幸な状況でサービスが利用できない場合は、起動スクリプトを変更してプロセスが終了するとすぐに問題を報告できます。
varnish || true some_command_to_send_an_alert_that_the_service_has_died
- または、サービスを開始するスクリプトを次のように変更します。PIDレコード、その後、定期的にヘルスチェックを使用してください
kill -0 "$pid"
。