一般的に、と単純なアプローチをしようとする悪い考えだ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
もう1つの問題は、パターンで使用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
プロセス)のパターンにヒットします。