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