2009-11-11 5 views
7

プロセスが開始または停止しているかどうかにかかわらず、このスクリプトが常に「実行中」を返す理由はありますか?if-statementは常にTRUEと評価されます

if ps ax | grep -v grep | grep "processName" > /dev/null 
then 
    echo $"running" 
else 
    echo $"not running" 
fi 

非常

ありがとうUPDATE: 私は多分間違って何かが他の場所であり、私のスクリプトの完全な例を追加します。

case "$1" in 
    start) 
    # Start daemons. 

    echo -n $"Starting daemon: " 
    ;; 

    stop) 
    # Stop daemons. 
    echo -n $"Shutting down: " 
    echo 
    ;; 
    status) 
    pgrep -f "ProcessName" > /dev/null 
    if [ $? -eq 0 ]; then 
     echo $"ProcessName is running" 
    else 
     echo $"ProcessName is not running" 
    fi 
    ;; 
    restart) 
    $0 stop 
    $0 start 
    ;; 

    *) 
    echo $"Usage: $0 {start|stop|status|restart}" 
    exit 1 
esac 

UPDATE 2:

[[email protected] init.d]# pgrep -f "MyProcess" > /dev/null 
[[email protected] init.d]# echo $? 
0 
[[email protected] init.d]# service MyProcess stop 
Shutting down MyProcess: Terminated 
[[email protected] init.d]# pgrep -f "MyProcess" > /dev/null 
[[email protected] init.d]# echo $? 
1 

しかし、すべての時間

+3

質問に答えるには、はいあります。 ;-) –

+0

@Mike、/ dev/nullへの出力リダイレクトを削除するとどうなるでしょうか?実際に実行中のプロセス、または同様の名前のものはありますか? – pilcrow

+0

@pilcrow私のプロセスが開始されると、プロセスの結果が表示されます。プロセスが停止すると、結果は表示されません。 – Mike

答えて

16

に代わりにこれを試してみてください:ProcessNameの手段の最初の文字の周り

ps aux | grep -q "[p]rocessName" 
if [ $? -eq 0 ]; then 
    echo "running" 
else 
    echo "not running" 
fi 

ブラケットが "を必要としないでくださいgrep -v grep "、-qは/ dev/nullへのパイプが不要であることを意味します。

$?実行された前のコマンドの戻りコードを返します。したがって、それが0であるかどうかをテストすることは、 "grep"が探していたものを見つけたかどうかを示します。

更新

あなたのプロセス名が(たとえば、「カップ」)本当に短い場合、それは(「のcupsdを」と言う)、あまりにも他のプロセスを一致させることとして、あなたは偽陽性を得る可能性があります。 grepを単語全体にマッチさせることでこれを克服することができます。-wフラグを追加してください。

この手法は完全ではありません。ユーザー名/日付フィールドに一致するエントリが表示されることがあります。それが起こった場合は、 "man ps"を調べ、grepを実行する前に印刷するものをさらに選択してください。または、出力をawkで事前にフィルタリングして、process/cmd名を示す列のみを抽出します。例えば:以下の回答で提案されているよう

ps aux | awk '{print $11}' | grep -q -w "[p]rocessName" 
if [ $? -eq 0 ]; then 
    echo "running" 
else 
    echo "not running" 
fi 

アップデート2

あなたものpgrep使用することができます。 (上記のように)オーバーマッチングを防止するために、本当に短いプロセス名について

、あなたは単語の境界を指定することもできますが(\ b)は、あなたのプロセス名の前と後の

pgrep "\bprocname\b" > /dev/null 
if [ $? -eq 0 ]; then 
    echo "running" 
else 
    echo "not running" 
fi 

アップデート3

更新された質問から、initスクリプトから実行していることがわかります。スクリプト自体に一致するpgrepの危険性は常にあります。試してください:

pgrep Processname | grep -q -v $$ 
if [ $? -eq 0 ]; then 
    echo "running" 
else 
    echo "not running" 
fi 

これは、pgrepの一致からスクリプトのPIDを除外します。

更新4

(最終更新?指が交差)

initスクリプトは、「サービス」コマンド経由で実行されている場合は、我々としても、親PIDをフィルタリングする必要があります。方法:

pgrep Processname | grep -v $$ | grep -q -v $PPID 
if [ $? -eq 0 ]; then 
    echo "running" 
else 
    echo "not running" 
fi 
+4

ちょっと、それは実際には[p] rocessnameを持つすてきなトリックです - 古い犬を証明するための+1は新しいトリックを学ぶことができます。 – paxdiablo

+0

私は試してみるといつも走ってきました。 – Mike

+0

彼は単にps aux | grep -q "[p] rocessName";エコーが走っている。そうでなければエコーは実行されませんfi 'を使った余分なテストは不要です。 –

-1

あなたがテストをやっていないTRUEであることをif [ $? -eq 0 ]; thenようです。そのような試験条件の周りに括弧を置く:

場合は、[あなたのテストを条件]

+1

[]がなければ、ifは与えられたコマンドの終了ステータスをテストします。そのため、彼のスクリプトはgrepの終了をテストしようとしています。 –

+0

@Emilはい彼が望む状態を効果的にテストしない!実際、大括弧のないanyAccessibleCommandがtrueを返す場合は – ennuikiller

+1

'if/bin/false;を試してください。エコーエンキーユーザは正しいです。 fi' – mob

2

おそらくgrep "processName"が見つかります。

[email protected]:~$ pgrep bash 
415 
3477 
[email protected]:~$ echo $? 
0 
[email protected]:~$ pgrep arf 
[email protected]:~$ echo $? 
1 
:私は xargあなたの代わりにあなたの psの文字列と様々な grep Sの pgrepコマンドを試してみたいかもしれない別の方法として kill ...

に結果をINGのしたことを除いて、昨日、この自己同じ問題を発見しました

+0

+1はpgrepを私に思い出させるために: –

+0

@Stephen、いいえ、OPは元のパイプラインの途中で "grep"を含むps行を除外します。 – pilcrow

+0

はい、pgrepは非常に柔軟です。 –

1

やあ、余談として

、代わりの

ps ax | grep -v grep | grep "processName" 

は、それが文字列「ProcessNameの」のためのあなたのgrepで渡されているプロセスリスト内の文字列「はgrep ProcessNameのを」見ているので、PSはgrepの機能を列挙している

ps ax | grep "[p]rocessName" 

やってみてください。

"[p] rocessName"のグリッピングは、 "processName"だけと一致しますが、文字列 "grep [p] rocessName"とは一致しません。

+0

良い観察。 pgrep、または '' ps ax -o comm | grep -q -w commandName ''、または任意の数のshellismが行います。しかし、これは答えではなく、OPの問題に対するコメントです... – pilcrow

関連する問題