スクリプトのps | grepから別の終了ステータスを取得するのはなぜですか?

スクリプトのps | grepから別の終了ステータスを取得するのはなぜですか?

次のスクリプトを実行しています。

#!/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ではsystemctlsystemctl 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.shtestというスクリプトを実行すると

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"

関連情報